Skip to content

Commit

Permalink
Refactor Move atomic actions from benchmark scenarios
Browse files Browse the repository at this point in the history
- Move atomic actions from benchmark/scenario/utils.py
to benchamrk/scenario/base.py
- Removed the scenario_utils imports
- Updated the scenario_base imports and related changes in
all rally files.

Closes-Bug:#1353464
Change-Id: I7f4d3e4b1d3650d97af08e5aca38fa80cc9f6fac
  • Loading branch information
Swapnil Kulkarni committed Aug 6, 2014
1 parent 4fbb79e commit 132722a
Show file tree
Hide file tree
Showing 49 changed files with 353 additions and 356 deletions.
19 changes: 9 additions & 10 deletions doc/source/benchmark.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,22 @@ In a toy example below, we define a scenario class *MyScenario* with one benchma

::

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios import utils


class MyScenario(base.Scenario):
class MyScenario(scenario_base.Scenario):
"""My class that contains benchmark scenarios."""

@utils.atomic_action_timer("action_1")
@scenario_base.atomic_action_timer("action_1")
def _action_1(self, **kwargs):
"""Do something with the cloud."""

@utils.atomic_action_timer("action_2")
@scenario_base.atomic_action_timer("action_2")
def _action_2(self, **kwargs):
"""Do something with the cloud."""

@base.scenario()
@scenario_base.scenario()
def scenario(self, **kwargs):
self._action_1()
self._action_2()
Expand Down Expand Up @@ -357,21 +357,20 @@ benchmark scenario results have been stored correctly.
import random
import time

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import utils as scenario_utils
from rally.benchmark.scenarios import base as scenario_base


class PluginClass(base.Scenario):

@scenario_utils.atomic_action_timer("test1")
@scenario_base.atomic_action_timer("test1")
def _test1(self, factor):
time.sleep(random.random() * factor)

@scenario_utils.atomic_action_timer("test2")
@scenario_base.atomic_action_timer("test2")
def _test2(self, factor):
time.sleep(random.random() * factor * 10)

@base.scenario()
@scenario_base.scenario()
def testplugin(self, factor=1):
self._test1(factor)
self._test2(factor)
Expand Down
11 changes: 5 additions & 6 deletions rally-scenarios/plugins/fake_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@
import random
import time

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import utils as scenario_utils
from rally.benchmark.scenarios import base as scenario_base


class FakePlugin(base.Scenario):
class FakePlugin(scenario_base.Scenario):

@scenario_utils.atomic_action_timer("test1")
@scenario_base.atomic_action_timer("test1")
def _test1(self, factor):
time.sleep(random.random())

@scenario_utils.atomic_action_timer("test2")
@scenario_base.atomic_action_timer("test2")
def _test2(self, factor):
time.sleep(random.random() * factor * 10)

@base.scenario()
@scenario_base.scenario()
def testplugin(self, factor=1):
self._test1(factor)
self._test2(factor)
4 changes: 2 additions & 2 deletions rally/benchmark/runners/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from oslo.config import cfg

from rally.benchmark.context import base as base_ctx
from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark import utils
from rally import consts
from rally import exceptions
Expand Down Expand Up @@ -199,7 +199,7 @@ def _run_scenario(self, cls, method_name, context, args):

def run(self, name, context, args):
cls_name, method_name = name.split(".", 1)
cls = base.Scenario.get_by_name(cls_name)
cls = scenario_base.Scenario.get_by_name(cls_name)

scenario_context = copy.deepcopy(getattr(cls, method_name).context)
# TODO(boris-42): We should keep default behavior for `users` context
Expand Down
39 changes: 19 additions & 20 deletions rally/benchmark/scenarios/authenticate/authenticate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@
# License for the specific language governing permissions and limitations
# under the License.

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import utils as scenario_utils
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark import validation


class Authenticate(base.Scenario):
class Authenticate(scenario_base.Scenario):
"""This class should contain authentication mechanism.
For different types of clients like Keystone.
"""

@base.scenario()
@scenario_utils.atomic_action_timer('authenticate.keystone')
@scenario_base.scenario()
@scenario_base.atomic_action_timer('authenticate.keystone')
def keystone(self, **kwargs):
self.clients("keystone")

@base.scenario()
@scenario_base.scenario()
@validation.add(validation.required_parameters(['repetitions']))
def validate_glance(self, repetitions):
"""Check Glance Client to ensure validation of token.
Expand All @@ -42,11 +41,11 @@ def validate_glance(self, repetitions):
glance_client = self.clients("glance")
image_name = "__intentionally_non_existent_image___"
for i in range(repetitions):
with scenario_utils.AtomicAction(self,
'authenticate.validate_glance'):
with scenario_base.AtomicAction(self,
'authenticate.validate_glance'):
list(glance_client.images.list(name=image_name))

@base.scenario()
@scenario_base.scenario()
@validation.add(validation.required_parameters(['repetitions']))
def validate_nova(self, repetitions):
"""Check Nova Client to ensure validation of token.
Expand All @@ -58,11 +57,11 @@ def validate_nova(self, repetitions):
"""
nova_client = self.clients("nova")
for i in range(repetitions):
with scenario_utils.AtomicAction(self,
'authenticate.validate_nova'):
with scenario_base.AtomicAction(self,
'authenticate.validate_nova'):
nova_client.flavors.list()

@base.scenario()
@scenario_base.scenario()
@validation.add(validation.required_parameters(['repetitions']))
def validate_cinder(self, repetitions):
"""Check Cinder Client to ensure validation of token.
Expand All @@ -74,11 +73,11 @@ def validate_cinder(self, repetitions):
"""
cinder_client = self.clients("cinder")
for i in range(repetitions):
with scenario_utils.AtomicAction(self,
'authenticate.validate_cinder'):
with scenario_base.AtomicAction(self,
'authenticate.validate_cinder'):
cinder_client.volume_types.list()

@base.scenario()
@scenario_base.scenario()
@validation.add(validation.required_parameters(['repetitions']))
def validate_neutron(self, repetitions):
"""Check Neutron Client to ensure validation of token.
Expand All @@ -90,11 +89,11 @@ def validate_neutron(self, repetitions):
"""
neutron_client = self.clients("neutron")
for i in range(repetitions):
with scenario_utils.AtomicAction(self,
'authenticate.validate_neutron'):
with scenario_base.AtomicAction(self,
'authenticate.validate_neutron'):
neutron_client.get_auth_info()

@base.scenario()
@scenario_base.scenario()
@validation.add(validation.required_parameters(['repetitions']))
def validate_heat(self, repetitions):
"""Check Heat Client to ensure validation of token.
Expand All @@ -106,6 +105,6 @@ def validate_heat(self, repetitions):
"""
heat_client = self.clients("heat")
for i in range(repetitions):
with scenario_utils.AtomicAction(self,
'authenticate.validate_heat'):
with scenario_base.AtomicAction(self,
'authenticate.validate_heat'):
list(heat_client.stacks.list(limit=0))
45 changes: 45 additions & 0 deletions rally/benchmark/scenarios/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.

import functools
import itertools
import random
import string
Expand Down Expand Up @@ -213,3 +214,47 @@ def _add_atomic_actions(self, name, duration):
def atomic_actions(self):
"""Returns the content of each atomic action."""
return self._atomic_actions


def atomic_action_timer(name):
"""Provide measure of execution time.
Decorates methods of the Scenario class.
This provides duration in seconds of each atomic action.
"""
def wrap(func):
@functools.wraps(func)
def func_atomic_actions(self, *args, **kwargs):
with utils.Timer() as timer:
f = func(self, *args, **kwargs)
self._add_atomic_actions(name, timer.duration())
return f
return func_atomic_actions
return wrap


class AtomicAction(utils.Timer):
"""A class to measure the duration of atomic operations
This would simplify the way measure atomic opeation duration
in certain cases. For example if we want to get the duration
for each operation which runs in an iteration
for i in range(repetitions):
with scenario_utils.AtomicAction(instance_of_base_scenario_subclass,
"name_of_action"):
self.clients(<client>).<operation>
"""

def __init__(self, scenario_instance, name):
"""Create a new instance of the AtomicAction.
:param scenario_instance: instance of subclass of base scenario
:param name: name of the ActionBuilder
"""
super(AtomicAction, self).__init__()
self.scenario_instance = scenario_instance
self.name = name

def __exit__(self, type, value, tb):
super(AtomicAction, self).__exit__(type, value, tb)
self.scenario_instance._add_atomic_actions(self.name, self.duration())
12 changes: 6 additions & 6 deletions rally/benchmark/scenarios/ceilometer/alarms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios.ceilometer import utils as ceilometerutils
from rally.benchmark import validation
from rally import consts


class CeilometerAlarms(ceilometerutils.CeilometerScenario):
@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_alarm(self, meter_name, threshold, **kwargs):
"""Test creating an alarm.
Expand All @@ -34,7 +34,7 @@ def create_alarm(self, meter_name, threshold, **kwargs):
"""
self._create_alarm(meter_name, threshold, kwargs)

@base.scenario()
@scenario_base.scenario()
@validation.required_services(consts.Service.CEILOMETER)
def list_alarms(self):
"""Test fetching all alarms.
Expand All @@ -43,7 +43,7 @@ def list_alarms(self):
"""
self._list_alarms()

@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_and_list_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and getting newly created alarm.
Expand All @@ -60,7 +60,7 @@ def create_and_list_alarm(self, meter_name, threshold, **kwargs):
alarm = self._create_alarm(meter_name, threshold, kwargs)
self._list_alarms(alarm.alarm_id)

@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_and_update_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and updating the newly created alarm.
Expand All @@ -78,7 +78,7 @@ def create_and_update_alarm(self, meter_name, threshold, **kwargs):
alarm_dict_diff = {"description": "Changed Test Description"}
self._update_alarm(alarm.alarm_id, alarm_dict_diff)

@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_and_delete_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and deleting the newly created alarm.
Expand Down
4 changes: 2 additions & 2 deletions rally/benchmark/scenarios/ceilometer/meters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios.ceilometer import utils as ceilometerutils
from rally.benchmark import validation
from rally import consts


class CeilometerMeters(ceilometerutils.CeilometerScenario):
@base.scenario()
@scenario_base.scenario()
@validation.required_services(consts.Service.CEILOMETER)
def list_meters(self):
"""Test fetching user's meters."""
Expand Down
8 changes: 4 additions & 4 deletions rally/benchmark/scenarios/ceilometer/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

import json

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios.ceilometer import utils as ceilometerutils
from rally.benchmark import validation
from rally import consts


class CeilometerQueries(ceilometerutils.CeilometerScenario):
@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_and_query_alarms(self, meter_name, threshold, filter=None,
orderby=None, limit=None, **kwargs):
Expand All @@ -42,7 +42,7 @@ def create_and_query_alarms(self, meter_name, threshold, filter=None,
self._create_alarm(meter_name, threshold, kwargs)
self._query_alarms(filter, orderby, limit)

@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_and_query_alarm_history(self, meter_name, threshold,
orderby=None, limit=None, **kwargs):
Expand All @@ -61,7 +61,7 @@ def create_and_query_alarm_history(self, meter_name, threshold,
alarm_filter = json.dumps({"=": {"alarm_id": alarm.alarm_id}})
self._query_alarm_history(alarm_filter, orderby, limit)

@base.scenario()
@scenario_base.scenario()
@validation.required_services(consts.Service.CEILOMETER)
def create_and_query_samples(self, counter_name, counter_type,
counter_unit, counter_volume, resource_id,
Expand Down
4 changes: 2 additions & 2 deletions rally/benchmark/scenarios/ceilometer/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios.ceilometer import utils as ceilometerutils
from rally.benchmark import validation
from rally import consts


class CeilometerResource(ceilometerutils.CeilometerScenario):
@base.scenario()
@scenario_base.scenario()
@validation.required_services(consts.Service.CEILOMETER)
def list_resources(self):
"""Test fetching all resources.
Expand Down
4 changes: 2 additions & 2 deletions rally/benchmark/scenarios/ceilometer/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# License for the specific language governing permissions and limitations
# under the License.

from rally.benchmark.scenarios import base
from rally.benchmark.scenarios import base as scenario_base
from rally.benchmark.scenarios.ceilometer import utils
from rally.benchmark import validation
from rally import consts


class CeilometerStats(utils.CeilometerScenario):
@base.scenario(context={"cleanup": ["ceilometer"]})
@scenario_base.scenario(context={"cleanup": ["ceilometer"]})
@validation.required_services(consts.Service.CEILOMETER)
def create_meter_and_get_stats(self, **kwargs):
"""Test creating a meter and fetching its statistics.
Expand Down
Loading

0 comments on commit 132722a

Please sign in to comment.