Add @validation.require_openstack() validator

This patch removes from @base.scenario(admin_only=False) argument.
That actually doesn't work and doesn't cover situation when we need
only users or admins or admins & users..

Add proper @require_openstack validator that actually checks
everything that is required.
So you can specify that only users or admin is required or both
users and admin are required.

Add missing "users" context in rally-scenario for scenarios that
use it.

Add missing "sla" sections in benchmarks

Reduce amount of iterations in "rps" benchmark

Change-Id: Ie92dbd473ee94c2073401c6da8dc2771c9dfaed8
This commit is contained in:
Boris Pavlovic 2014-09-05 14:41:13 +04:00
parent f109e72ced
commit e9f18c1a0d
23 changed files with 275 additions and 36 deletions

View File

@ -95,6 +95,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -112,6 +116,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -129,6 +137,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -146,6 +158,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -155,6 +171,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -164,6 +184,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -173,6 +197,10 @@
type: "constant" type: "constant"
times: 10 times: 10
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -192,9 +220,8 @@
sleep: 0.001 sleep: 0.001
runner: runner:
type: "rps" type: "rps"
times: 10000 times: 2000
rps: 200 rps: 200
timeout: 600
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -283,6 +310,12 @@
type: "constant" type: "constant"
times: 20 times: 20
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla:
max_failure_percent: 0
CeilometerQueries.create_and_query_alarms: CeilometerQueries.create_and_query_alarms:
- -
@ -301,6 +334,10 @@
type: "constant" type: "constant"
times: 20 times: 20
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -320,6 +357,10 @@
type: "constant" type: "constant"
times: 20 times: 20
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla: sla:
max_failure_percent: 0 max_failure_percent: 0
@ -338,6 +379,12 @@
type: "constant" type: "constant"
times: 20 times: 20
concurrency: 10 concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
sla:
max_failure_percent: 0
HeatStacks.create_and_list_stack: HeatStacks.create_and_list_stack:
- -
@ -609,6 +656,8 @@
users: users:
tenants: 2 tenants: 2
users_per_tenant: 2 users_per_tenant: 2
sla:
max_failure_percent: 0
GlanceImages.create_and_delete_image: GlanceImages.create_and_delete_image:
- -

View File

@ -22,11 +22,13 @@ class Authenticate(base.Scenario):
For different types of clients like Keystone. For different types of clients like Keystone.
""" """
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def keystone(self, **kwargs): def keystone(self, **kwargs):
self.clients("keystone") self.clients("keystone")
@validation.required_parameters("repetitions") @validation.number("repetitions", minval=1)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def validate_glance(self, repetitions): def validate_glance(self, repetitions):
"""Check Glance Client to ensure validation of token. """Check Glance Client to ensure validation of token.
@ -43,7 +45,8 @@ class Authenticate(base.Scenario):
with base.AtomicAction(self, "authenticate.validate_glance"): with base.AtomicAction(self, "authenticate.validate_glance"):
list(glance_client.images.list(name=image_name)) list(glance_client.images.list(name=image_name))
@validation.required_parameters("repetitions") @validation.number("repetitions", minval=1)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def validate_nova(self, repetitions): def validate_nova(self, repetitions):
"""Check Nova Client to ensure validation of token. """Check Nova Client to ensure validation of token.
@ -58,7 +61,8 @@ class Authenticate(base.Scenario):
with base.AtomicAction(self, "authenticate.validate_nova"): with base.AtomicAction(self, "authenticate.validate_nova"):
nova_client.flavors.list() nova_client.flavors.list()
@validation.required_parameters("repetitions") @validation.number("repetitions", minval=1)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def validate_cinder(self, repetitions): def validate_cinder(self, repetitions):
"""Check Cinder Client to ensure validation of token. """Check Cinder Client to ensure validation of token.
@ -73,7 +77,8 @@ class Authenticate(base.Scenario):
with base.AtomicAction(self, "authenticate.validate_cinder"): with base.AtomicAction(self, "authenticate.validate_cinder"):
cinder_client.volume_types.list() cinder_client.volume_types.list()
@validation.required_parameters("repetitions") @validation.number("repetitions", minval=1)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def validate_neutron(self, repetitions): def validate_neutron(self, repetitions):
"""Check Neutron Client to ensure validation of token. """Check Neutron Client to ensure validation of token.
@ -88,7 +93,8 @@ class Authenticate(base.Scenario):
with base.AtomicAction(self, "authenticate.validate_neutron"): with base.AtomicAction(self, "authenticate.validate_neutron"):
neutron_client.get_auth_info() neutron_client.get_auth_info()
@validation.required_parameters("repetitions") @validation.number("repetitions", minval=1)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def validate_heat(self, repetitions): def validate_heat(self, repetitions):
"""Check Heat Client to ensure validation of token. """Check Heat Client to ensure validation of token.

View File

@ -25,17 +25,17 @@ from rally import exceptions
from rally import utils from rally import utils
def scenario(admin_only=False, context=None): def scenario(context=None):
"""Add extra fields to benchmark scenarios methods. """Make from plain python method benchmark.
This method is used as decorator for the methods of benchmark scenarios It sets 2 attributes to function:
and it adds following extra fields to the methods. is_scenario = True # that is used during discovering
'is_scenario' is set to True func.context = context # default context for benchmark
'admin_only' is set to True if a scenario require admin endpoints
:param context: Default benchmark context
""" """
def wrapper(func): def wrapper(func):
func.is_scenario = True func.is_scenario = True
func.admin_only = admin_only
func.context = context or {} func.context = context or {}
return func return func
return wrapper return wrapper

View File

@ -21,6 +21,7 @@ from rally import consts
class CeilometerAlarms(ceilometerutils.CeilometerScenario): class CeilometerAlarms(ceilometerutils.CeilometerScenario):
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_alarm(self, meter_name, threshold, **kwargs): def create_alarm(self, meter_name, threshold, **kwargs):
"""Test creating an alarm. """Test creating an alarm.
@ -36,6 +37,7 @@ class CeilometerAlarms(ceilometerutils.CeilometerScenario):
self._create_alarm(meter_name, threshold, kwargs) self._create_alarm(meter_name, threshold, kwargs)
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def list_alarms(self): def list_alarms(self):
"""Test fetching all alarms. """Test fetching all alarms.
@ -45,6 +47,7 @@ class CeilometerAlarms(ceilometerutils.CeilometerScenario):
self._list_alarms() self._list_alarms()
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_list_alarm(self, meter_name, threshold, **kwargs): def create_and_list_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and getting newly created alarm. """Test creating and getting newly created alarm.
@ -62,6 +65,7 @@ class CeilometerAlarms(ceilometerutils.CeilometerScenario):
self._list_alarms(alarm.alarm_id) self._list_alarms(alarm.alarm_id)
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_update_alarm(self, meter_name, threshold, **kwargs): def create_and_update_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and updating the newly created alarm. """Test creating and updating the newly created alarm.
@ -80,6 +84,7 @@ class CeilometerAlarms(ceilometerutils.CeilometerScenario):
self._update_alarm(alarm.alarm_id, alarm_dict_diff) self._update_alarm(alarm.alarm_id, alarm_dict_diff)
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_delete_alarm(self, meter_name, threshold, **kwargs): def create_and_delete_alarm(self, meter_name, threshold, **kwargs):
"""Test creating and deleting the newly created alarm. """Test creating and deleting the newly created alarm.

View File

@ -21,6 +21,7 @@ from rally import consts
class CeilometerMeters(ceilometerutils.CeilometerScenario): class CeilometerMeters(ceilometerutils.CeilometerScenario):
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def list_meters(self): def list_meters(self):
"""Test fetching user's meters.""" """Test fetching user's meters."""

View File

@ -23,6 +23,7 @@ from rally import consts
class CeilometerQueries(ceilometerutils.CeilometerScenario): class CeilometerQueries(ceilometerutils.CeilometerScenario):
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_alarms(self, meter_name, threshold, filter=None, def create_and_query_alarms(self, meter_name, threshold, filter=None,
orderby=None, limit=None, **kwargs): orderby=None, limit=None, **kwargs):
@ -44,6 +45,7 @@ class CeilometerQueries(ceilometerutils.CeilometerScenario):
self._query_alarms(filter, orderby, limit) self._query_alarms(filter, orderby, limit)
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_alarm_history(self, meter_name, threshold, def create_and_query_alarm_history(self, meter_name, threshold,
orderby=None, limit=None, **kwargs): orderby=None, limit=None, **kwargs):
@ -63,6 +65,7 @@ class CeilometerQueries(ceilometerutils.CeilometerScenario):
self._query_alarm_history(alarm_filter, orderby, limit) self._query_alarm_history(alarm_filter, orderby, limit)
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_and_query_samples(self, counter_name, counter_type, def create_and_query_samples(self, counter_name, counter_type,
counter_unit, counter_volume, resource_id, counter_unit, counter_volume, resource_id,

View File

@ -21,6 +21,7 @@ from rally import consts
class CeilometerResource(ceilometerutils.CeilometerScenario): class CeilometerResource(ceilometerutils.CeilometerScenario):
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario() @base.scenario()
def list_resources(self): def list_resources(self):
"""Test fetching all resources. """Test fetching all resources.

View File

@ -21,6 +21,7 @@ from rally import consts
class CeilometerStats(utils.CeilometerScenario): class CeilometerStats(utils.CeilometerScenario):
@validation.required_services(consts.Service.CEILOMETER) @validation.required_services(consts.Service.CEILOMETER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["ceilometer"]}) @base.scenario(context={"cleanup": ["ceilometer"]})
def create_meter_and_get_stats(self, **kwargs): def create_meter_and_get_stats(self, **kwargs):
"""Test creating a meter and fetching its statistics. """Test creating a meter and fetching its statistics.

View File

@ -25,6 +25,7 @@ class CinderVolumes(utils.CinderScenario,
nova_utils.NovaScenario): nova_utils.NovaScenario):
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["cinder"]}) @base.scenario(context={"cleanup": ["cinder"]})
def create_and_list_volume(self, size, detailed=True, **kwargs): def create_and_list_volume(self, size, detailed=True, **kwargs):
"""Tests creating a volume and listing volumes. """Tests creating a volume and listing volumes.
@ -43,6 +44,7 @@ class CinderVolumes(utils.CinderScenario,
self._list_volumes(detailed) self._list_volumes(detailed)
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["cinder"]}) @base.scenario(context={"cleanup": ["cinder"]})
def create_and_delete_volume(self, size, min_sleep=0, max_sleep=0, def create_and_delete_volume(self, size, min_sleep=0, max_sleep=0,
**kwargs): **kwargs):
@ -56,6 +58,7 @@ class CinderVolumes(utils.CinderScenario,
self._delete_volume(volume) self._delete_volume(volume)
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["cinder"]}) @base.scenario(context={"cleanup": ["cinder"]})
def create_volume(self, size, **kwargs): def create_volume(self, size, **kwargs):
"""Test creating volumes perfromance. """Test creating volumes perfromance.
@ -65,9 +68,10 @@ class CinderVolumes(utils.CinderScenario,
""" """
self._create_volume(size, **kwargs) self._create_volume(size, **kwargs)
@base.scenario(context={"cleanup": ["cinder"]})
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@validation.required_contexts("volumes") @validation.required_contexts("volumes")
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["cinder"]})
def create_and_delete_snapshot(self, force=False, min_sleep=0, def create_and_delete_snapshot(self, force=False, min_sleep=0,
max_sleep=0, **kwargs): max_sleep=0, **kwargs):
"""Tests creating and then deleting a volume-snapshot.""" """Tests creating and then deleting a volume-snapshot."""
@ -85,6 +89,7 @@ class CinderVolumes(utils.CinderScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_services(consts.Service.NOVA, consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["cinder", "nova"]}) @base.scenario(context={"cleanup": ["cinder", "nova"]})
def create_and_attach_volume(self, volume_size, image, flavor, def create_and_attach_volume(self, volume_size, image, flavor,
min_sleep=0, max_sleep=0, **kwargs): min_sleep=0, max_sleep=0, **kwargs):

View File

@ -23,6 +23,7 @@ from rally import consts
class DesignateBasic(utils.DesignateScenario): class DesignateBasic(utils.DesignateScenario):
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def create_and_list_domains(self): def create_and_list_domains(self):
"""Tests creating a domain and listing domains. """Tests creating a domain and listing domains.
@ -40,6 +41,7 @@ class DesignateBasic(utils.DesignateScenario):
self._list_domains() self._list_domains()
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def list_domains(self): def list_domains(self):
"""Test the designate domain-list command. """Test the designate domain-list command.
@ -55,6 +57,7 @@ class DesignateBasic(utils.DesignateScenario):
self._list_domains() self._list_domains()
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def create_and_delete_domain(self): def create_and_delete_domain(self):
"""Test adds and then deletes domain. """Test adds and then deletes domain.
@ -66,6 +69,7 @@ class DesignateBasic(utils.DesignateScenario):
self._delete_domain(domain['id']) self._delete_domain(domain['id'])
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def create_and_delete_records(self, records_per_domain=5): def create_and_delete_records(self, records_per_domain=5):
"""Test adds and then deletes records. """Test adds and then deletes records.
@ -92,6 +96,7 @@ class DesignateBasic(utils.DesignateScenario):
domain['id'], record['id'], atomic_action=False) domain['id'], record['id'], atomic_action=False)
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def list_records(self, domain_id): def list_records(self, domain_id):
"""Test the designate record-list command. """Test the designate record-list command.
@ -109,6 +114,7 @@ class DesignateBasic(utils.DesignateScenario):
self._list_records(domain_id) self._list_records(domain_id)
@validation.required_services(consts.Service.DESIGNATE) @validation.required_services(consts.Service.DESIGNATE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["designate"]}) @base.scenario(context={"cleanup": ["designate"]})
def create_and_list_records(self, records_per_domain=5): def create_and_list_records(self, records_per_domain=5):
"""Test adds and then lists records. """Test adds and then lists records.

View File

@ -27,6 +27,7 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
RESOURCE_NAME_LENGTH = 16 RESOURCE_NAME_LENGTH = 16
@validation.required_services(consts.Service.GLANCE) @validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["glance"]}) @base.scenario(context={"cleanup": ["glance"]})
def create_and_list_image(self, container_format, def create_and_list_image(self, container_format,
image_location, disk_format, **kwargs): image_location, disk_format, **kwargs):
@ -49,6 +50,7 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
self._list_images() self._list_images()
@validation.required_services(consts.Service.GLANCE) @validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["glance"]}) @base.scenario(context={"cleanup": ["glance"]})
def list_images(self): def list_images(self):
"""Test the glance image-list command. """Test the glance image-list command.
@ -64,6 +66,7 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
self._list_images() self._list_images()
@validation.required_services(consts.Service.GLANCE) @validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["glance"]}) @base.scenario(context={"cleanup": ["glance"]})
def create_and_delete_image(self, container_format, def create_and_delete_image(self, container_format,
image_location, disk_format, **kwargs): image_location, disk_format, **kwargs):
@ -79,6 +82,7 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
@types.set(flavor=types.FlavorResourceType) @types.set(flavor=types.FlavorResourceType)
@validation.flavor_exists("flavor") @validation.flavor_exists("flavor")
@validation.required_services(consts.Service.GLANCE, consts.Service.NOVA) @validation.required_services(consts.Service.GLANCE, consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["glance", "nova"]}) @base.scenario(context={"cleanup": ["glance", "nova"]})
def create_image_and_boot_instances(self, container_format, def create_image_and_boot_instances(self, container_format,
image_location, disk_format, image_location, disk_format,

View File

@ -36,6 +36,7 @@ class HeatStacks(utils.HeatScenario):
return template return template
@validation.required_services(consts.Service.HEAT) @validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"], @base.scenario(context={"cleanup": ["heat"],
"roles": ["heat_stack_owner"]}) "roles": ["heat_stack_owner"]})
def create_and_list_stack(self, template_path=None): def create_and_list_stack(self, template_path=None):
@ -55,6 +56,7 @@ class HeatStacks(utils.HeatScenario):
self._list_stacks() self._list_stacks()
@validation.required_services(consts.Service.HEAT) @validation.required_services(consts.Service.HEAT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["heat"], @base.scenario(context={"cleanup": ["heat"],
"roles": ["heat_stack_owner"]}) "roles": ["heat_stack_owner"]})
def create_and_delete_stack(self, template_path=None): def create_and_delete_stack(self, template_path=None):

View File

@ -20,33 +20,45 @@ from rally.benchmark import validation
class KeystoneBasic(kutils.KeystoneScenario): class KeystoneBasic(kutils.KeystoneScenario):
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("name_length", minval=10)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_user(self, name_length=10, **kwargs): def create_user(self, name_length=10, **kwargs):
self._user_create(name_length=name_length, **kwargs) self._user_create(name_length=name_length, **kwargs)
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("name_length", minval=10)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_delete_user(self, name_length=10, **kwargs): def create_delete_user(self, name_length=10, **kwargs):
user = self._user_create(name_length=name_length, **kwargs) user = self._user_create(name_length=name_length, **kwargs)
self._resource_delete(user) self._resource_delete(user)
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("name_length", minval=10)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_tenant(self, name_length=10, **kwargs): def create_tenant(self, name_length=10, **kwargs):
self._tenant_create(name_length=name_length, **kwargs) self._tenant_create(name_length=name_length, **kwargs)
@validation.required_parameters("users_per_tenant") @validation.number("name_length", minval=10)
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("users_per_tenant", minval=1)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_tenant_with_users(self, users_per_tenant, name_length=10, def create_tenant_with_users(self, users_per_tenant, name_length=10,
**kwargs): **kwargs):
tenant = self._tenant_create(name_length=name_length, **kwargs) tenant = self._tenant_create(name_length=name_length, **kwargs)
self._users_create(tenant, users_per_tenant=users_per_tenant, self._users_create(tenant, users_per_tenant=users_per_tenant,
name_length=name_length) name_length=name_length)
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("name_length", minval=10)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_and_list_users(self, name_length=10, **kwargs): def create_and_list_users(self, name_length=10, **kwargs):
self._user_create(name_length=name_length, **kwargs) self._user_create(name_length=name_length, **kwargs)
self._list_users() self._list_users()
@base.scenario(admin_only=True, context={"admin_cleanup": ["keystone"]}) @validation.number("name_length", minval=10)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["keystone"]})
def create_and_list_tenants(self, name_length=10, **kwargs): def create_and_list_tenants(self, name_length=10, **kwargs):
self._tenant_create(name_length=name_length, **kwargs) self._tenant_create(name_length=name_length, **kwargs)
self._list_tenants() self._list_tenants()

View File

@ -22,6 +22,7 @@ from rally import consts
class NeutronNetworks(utils.NeutronScenario): class NeutronNetworks(utils.NeutronScenario):
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_list_networks(self, network_create_args=None): def create_and_list_networks(self, network_create_args=None):
"""Create a network and then listing all networks. """Create a network and then listing all networks.
@ -41,6 +42,7 @@ class NeutronNetworks(utils.NeutronScenario):
self._list_networks() self._list_networks()
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_delete_networks(self, network_create_args=None): def create_and_delete_networks(self, network_create_args=None):
"""Create a network and then deleting it. """Create a network and then deleting it.
@ -53,8 +55,9 @@ class NeutronNetworks(utils.NeutronScenario):
network = self._create_network(network_create_args or {}) network = self._create_network(network_create_args or {})
self._delete_network(network['network']) self._delete_network(network['network'])
@validation.required_parameters("subnets_per_network") @validation.number("subnets_per_network", minval=1, integer_only=True)
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_list_subnets(self, def create_and_list_subnets(self,
network_create_args=None, network_create_args=None,
@ -80,8 +83,9 @@ class NeutronNetworks(utils.NeutronScenario):
self._list_subnets() self._list_subnets()
@validation.required_parameters("subnets_per_network") @validation.number("subnets_per_network", minval=1, integer_only=True)
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_delete_subnets(self, def create_and_delete_subnets(self,
network_create_args=None, network_create_args=None,
@ -107,8 +111,9 @@ class NeutronNetworks(utils.NeutronScenario):
subnet_create_args or {}) subnet_create_args or {})
self._delete_subnet(subnet) self._delete_subnet(subnet)
@validation.required_parameters("subnets_per_network") @validation.number("subnets_per_network", minval=1, integer_only=True)
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_list_routers(self, def create_and_list_routers(self,
network_create_args=None, network_create_args=None,
@ -140,8 +145,9 @@ class NeutronNetworks(utils.NeutronScenario):
self._list_routers() self._list_routers()
@validation.required_parameters("ports_per_network") @validation.number("ports_per_network", minval=1, integer_only=True)
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_list_ports(self, def create_and_list_ports(self,
network_create_args=None, network_create_args=None,
@ -159,8 +165,9 @@ class NeutronNetworks(utils.NeutronScenario):
self._list_ports() self._list_ports()
@validation.required_parameters("ports_per_network") @validation.number("ports_per_network", minval=1, integer_only=True)
@validation.required_services(consts.Service.NEUTRON) @validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["neutron"]}) @base.scenario(context={"cleanup": ["neutron"]})
def create_and_delete_ports(self, def create_and_delete_ports(self,
network_create_args=None, network_create_args=None,

View File

@ -39,6 +39,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova"]}) @base.scenario(context={"cleanup": ["nova"]})
def boot_and_list_server(self, image, flavor, def boot_and_list_server(self, image, flavor,
detailed=True, **kwargs): detailed=True, **kwargs):
@ -61,6 +62,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova"]}) @base.scenario(context={"cleanup": ["nova"]})
def boot_and_delete_server(self, image, flavor, def boot_and_delete_server(self, image, flavor,
min_sleep=0, max_sleep=0, **kwargs): min_sleep=0, max_sleep=0, **kwargs):
@ -74,6 +76,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_services(consts.Service.NOVA, consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova", "cinder"]}) @base.scenario(context={"cleanup": ["nova", "cinder"]})
def boot_server_from_volume_and_delete(self, image, flavor, def boot_server_from_volume_and_delete(self, image, flavor,
volume_size, volume_size,
@ -92,6 +95,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova"]}) @base.scenario(context={"cleanup": ["nova"]})
def boot_and_bounce_server(self, image, flavor, **kwargs): def boot_and_bounce_server(self, image, flavor, **kwargs):
"""Test booting a server with further performing specified actions. """Test booting a server with further performing specified actions.
@ -118,6 +122,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA, consts.Service.GLANCE) @validation.required_services(consts.Service.NOVA, consts.Service.GLANCE)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova", "glance"]}) @base.scenario(context={"cleanup": ["nova", "glance"]})
def snapshot_server(self, image, flavor, **kwargs): def snapshot_server(self, image, flavor, **kwargs):
"""Tests Nova instance snapshotting.""" """Tests Nova instance snapshotting."""
@ -135,6 +140,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova"]}) @base.scenario(context={"cleanup": ["nova"]})
def boot_server(self, image, flavor, auto_assign_nic=False, **kwargs): def boot_server(self, image, flavor, auto_assign_nic=False, **kwargs):
"""Test VM boot - assumed clean-up is done elsewhere.""" """Test VM boot - assumed clean-up is done elsewhere."""
@ -146,6 +152,7 @@ class NovaServers(utils.NovaScenario,
flavor=types.FlavorResourceType) flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_services(consts.Service.NOVA, consts.Service.CINDER)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova", "cinder"]}) @base.scenario(context={"cleanup": ["nova", "cinder"]})
def boot_server_from_volume(self, image, flavor, volume_size, def boot_server_from_volume(self, image, flavor, volume_size,
auto_assign_nic=False, **kwargs): auto_assign_nic=False, **kwargs):
@ -203,6 +210,7 @@ class NovaServers(utils.NovaScenario,
to_flavor=types.FlavorResourceType) to_flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["nova"]}) @base.scenario(context={"cleanup": ["nova"]})
def resize_server(self, image, flavor, to_flavor, **kwargs): def resize_server(self, image, flavor, to_flavor, **kwargs):
"""Tests resize serveri.""" """Tests resize serveri."""

View File

@ -22,7 +22,8 @@ from rally import consts
class Quotas(utils.QuotasScenario): class Quotas(utils.QuotasScenario):
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@base.scenario(admin_only=True, context={"admin_cleanup": ["quotas"]}) @validation.required_openstack(admin=True, users=True)
@base.scenario(context={"admin_cleanup": ["quotas"]})
def nova_update(self, max_quota=1024): def nova_update(self, max_quota=1024):
"""Tests updating quotas for nova. """Tests updating quotas for nova.
@ -32,7 +33,8 @@ class Quotas(utils.QuotasScenario):
self._update_quotas('nova', tenant_id, max_quota) self._update_quotas('nova', tenant_id, max_quota)
@validation.required_services(consts.Service.NOVA) @validation.required_services(consts.Service.NOVA)
@base.scenario(admin_only=True, context={"admin_cleanup": ["quotas"]}) @validation.required_openstack(admin=True, users=True)
@base.scenario(context={"admin_cleanup": ["quotas"]})
def nova_update_and_delete(self, max_quota=1024): def nova_update_and_delete(self, max_quota=1024):
"""Tests updating and deleting quotas for nova. """Tests updating and deleting quotas for nova.
@ -44,7 +46,8 @@ class Quotas(utils.QuotasScenario):
self._delete_quotas('nova', tenant_id) self._delete_quotas('nova', tenant_id)
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@base.scenario(admin_only=True, context={"admin_cleanup": ["quotas"]}) @validation.required_openstack(admin=True, users=True)
@base.scenario(context={"admin_cleanup": ["quotas"]})
def cinder_update(self, max_quota=1024): def cinder_update(self, max_quota=1024):
"""Tests updating quotas for cinder. """Tests updating quotas for cinder.
@ -54,7 +57,8 @@ class Quotas(utils.QuotasScenario):
self._update_quotas('cinder', tenant_id, max_quota) self._update_quotas('cinder', tenant_id, max_quota)
@validation.required_services(consts.Service.CINDER) @validation.required_services(consts.Service.CINDER)
@base.scenario(admin_only=True, context={"admin_cleanup": ["quotas"]}) @validation.required_openstack(admin=True, users=True)
@base.scenario(context={"admin_cleanup": ["quotas"]})
def cinder_update_and_delete(self, max_quota=1024): def cinder_update_and_delete(self, max_quota=1024):
"""Tests updating and deleting quotas for cinder. """Tests updating and deleting quotas for cinder.

View File

@ -12,7 +12,7 @@
import requests import requests
from rally.benchmark.scenarios import base as scenario_base from rally.benchmark.scenarios import base
from rally import exceptions from rally import exceptions
from rally.openstack.common.gettextutils import _ from rally.openstack.common.gettextutils import _
@ -21,10 +21,10 @@ class WrongStatusException(exceptions.RallyException):
msg_fmt = _("Requests scenario exception: '%(message)s'") msg_fmt = _("Requests scenario exception: '%(message)s'")
class Requests(scenario_base.Scenario): class Requests(base.Scenario):
"""This class should contain all the http_request scenarios.""" """This class should contain all the http_request scenarios."""
@scenario_base.scenario() @base.scenario()
def check_response(self, url, response=None): def check_response(self, url, response=None):
"""Standard way to benchmark web services. """Standard way to benchmark web services.

View File

@ -27,9 +27,10 @@ class SaharaClusters(utils.SaharaScenario):
@types.set(flavor=types.FlavorResourceType) @types.set(flavor=types.FlavorResourceType)
@validation.flavor_exists('flavor') @validation.flavor_exists('flavor')
@validation.required_services(consts.Service.SAHARA)
@validation.required_contexts("users", "sahara_image") @validation.required_contexts("users", "sahara_image")
@validation.number("node_count", minval=2, integer_only=True) @validation.number("node_count", minval=2, integer_only=True)
@validation.required_services(consts.Service.SAHARA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["sahara"]}) @base.scenario(context={"cleanup": ["sahara"]})
def create_and_delete_cluster(self, flavor, node_count, plugin_name, def create_and_delete_cluster(self, flavor, node_count, plugin_name,
hadoop_version, floating_ip_pool=None, hadoop_version, floating_ip_pool=None,

View File

@ -25,6 +25,7 @@ class SaharaNodeGroupTemplates(utils.SaharaScenario):
@types.set(flavor=types.FlavorResourceType) @types.set(flavor=types.FlavorResourceType)
@validation.flavor_exists('flavor') @validation.flavor_exists('flavor')
@validation.required_services(consts.Service.SAHARA) @validation.required_services(consts.Service.SAHARA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["sahara"]}) @base.scenario(context={"cleanup": ["sahara"]})
def create_and_list_node_group_templates(self, flavor, def create_and_list_node_group_templates(self, flavor,
plugin_name="vanilla", plugin_name="vanilla",
@ -59,6 +60,7 @@ class SaharaNodeGroupTemplates(utils.SaharaScenario):
@types.set(flavor=types.FlavorResourceType) @types.set(flavor=types.FlavorResourceType)
@validation.flavor_exists('flavor') @validation.flavor_exists('flavor')
@validation.required_services(consts.Service.SAHARA) @validation.required_services(consts.Service.SAHARA)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["sahara"]}) @base.scenario(context={"cleanup": ["sahara"]})
def create_delete_node_group_templates(self, flavor, def create_delete_node_group_templates(self, flavor,
plugin_name="vanilla", plugin_name="vanilla",

View File

@ -22,6 +22,7 @@ from rally import consts
class TempestScenario(base.Scenario): class TempestScenario(base.Scenario):
@validation.tempest_tests_exists() @validation.tempest_tests_exists()
@validation.required_openstack(admin=True)
@base.scenario(context={"tempest": {}}) @base.scenario(context={"tempest": {}})
@utils.tempest_log_wrapper @utils.tempest_log_wrapper
def single_test(self, test_name, log_file): def single_test(self, test_name, log_file):
@ -36,6 +37,7 @@ class TempestScenario(base.Scenario):
self.context()["verifier"].run(test_name, log_file) self.context()["verifier"].run(test_name, log_file)
@validation.required_openstack(admin=True)
@base.scenario(context={"tempest": {}}) @base.scenario(context={"tempest": {}})
@utils.tempest_log_wrapper @utils.tempest_log_wrapper
def all(self, log_file): def all(self, log_file):
@ -47,6 +49,7 @@ class TempestScenario(base.Scenario):
self.context()["verifier"].run("", log_file) self.context()["verifier"].run("", log_file)
@validation.tempest_set_exists() @validation.tempest_set_exists()
@validation.required_openstack(admin=True)
@base.scenario(context={"tempest": {}}) @base.scenario(context={"tempest": {}})
@utils.tempest_log_wrapper @utils.tempest_log_wrapper
def set(self, set_name, log_file): def set(self, set_name, log_file):
@ -66,6 +69,7 @@ class TempestScenario(base.Scenario):
self._context["verifier"].run(testr_arg, log_file) self._context["verifier"].run(testr_arg, log_file)
@validation.tempest_tests_exists() @validation.tempest_tests_exists()
@validation.required_openstack(admin=True)
@base.scenario(context={"tempest": {}}) @base.scenario(context={"tempest": {}})
@utils.tempest_log_wrapper @utils.tempest_log_wrapper
def list_of_tests(self, test_names, log_file): def list_of_tests(self, test_names, log_file):
@ -77,6 +81,7 @@ class TempestScenario(base.Scenario):
self._context["verifier"].run(" ".join(test_names), log_file) self._context["verifier"].run(" ".join(test_names), log_file)
@validation.required_openstack(admin=True)
@base.scenario(context={"tempest": {}}) @base.scenario(context={"tempest": {}})
@utils.tempest_log_wrapper @utils.tempest_log_wrapper
def specific_regex(self, regex, log_file): def specific_regex(self, regex, log_file):

View File

@ -36,9 +36,10 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario):
@validation.number("port", minval=1, maxval=65535, nullable=True, @validation.number("port", minval=1, maxval=65535, nullable=True,
integer_only=True) integer_only=True)
@validation.external_network_exists("floating_network", "use_floatingip") @validation.external_network_exists("floating_network", "use_floatingip")
@validation.required_services(consts.Service.NOVA)
@validation.required_openstack(users=True)
@base.scenario( @base.scenario(
context={"cleanup": ["nova"], "keypair": {}, "allow_ssh": {}}) context={"cleanup": ["nova"], "keypair": {}, "allow_ssh": {}})
@validation.required_services(consts.Service.NOVA)
def boot_runcommand_delete(self, image, flavor, def boot_runcommand_delete(self, image, flavor,
script, interpreter, username, script, interpreter, username,
fixed_network="private", fixed_network="private",

View File

@ -22,6 +22,7 @@ from novaclient import exceptions as nova_exc
from rally.benchmark import types as types from rally.benchmark import types as types
from rally import consts from rally import consts
from rally import exceptions from rally import exceptions
from rally import objects
from rally.openstack.common.gettextutils import _ from rally.openstack.common.gettextutils import _
from rally.verification.verifiers.tempest import tempest from rally.verification.verifiers.tempest import tempest
@ -376,3 +377,38 @@ def required_contexts(config, clients, task, *context_names):
return ValidationResult(False, message) return ValidationResult(False, message)
else: else:
return ValidationResult() return ValidationResult()
@validator
def required_openstack(config, clients, task, admin=False, users=False):
"""Validator that requires OpenStack admin or (and) users.
This allows us to create 4 kind of benchmarks:
1) not OpenStack related (validator is not specified)
2) requires OpenStack admin
3) requires OpenStack admin + users
4) requires OpenStack users
:param admin: requires OpenStack admin
:param users: requires OpenStack users
"""
if not (admin or users):
return ValidationResult(
False, _("You should specify admin=True or users=True or both."))
deployment = objects.Deployment.get(task["deployment_uuid"])
if deployment["admin"] and deployment["users"]:
return ValidationResult()
if deployment["admin"]:
if users and not config.get("context", {}).get("users"):
return ValidationResult(False,
_("You should specify 'users' context"))
return ValidationResult()
if deployment["users"] and admin:
return ValidationResult(False, _("Admin credentials required"))
return ValidationResult()

View File

@ -385,3 +385,83 @@ class ValidatorsTestCase(test.TestCase):
result = validator({"context": {"c1": 1, "c2": 2, "c3": 3, "a": 1}}, result = validator({"context": {"c1": 1, "c2": 2, "c3": 3, "a": 1}},
None, None) None, None)
self.assertTrue(result.is_valid, result.msg) self.assertTrue(result.is_valid, result.msg)
@mock.patch("rally.benchmark.validation.objects.Deployment.get")
def test_required_openstack_with_admin(self, mock_deploy_get):
validator = self._unwrap_validator(validation.required_openstack,
admin=True)
# admin presented in deployment
task = {"deployment_uuid": mock.MagicMock()}
mock_deploy_get.return_value = {"admin": "admin_endpoint", "users": []}
self.assertTrue(validator(None, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
# admin not presented in deployment
mock_deploy_get.return_value = {"admin": None, "users": ["u1", "h2"]}
self.assertFalse(validator(None, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
@mock.patch("rally.benchmark.validation.objects.Deployment.get")
def test_required_openstack_with_users(self, mock_deploy_get):
validator = self._unwrap_validator(validation.required_openstack,
users=True)
# users presented in deployment
task = {"deployment_uuid": mock.MagicMock()}
mock_deploy_get.return_value = {"admin": None, "users": ["u_endpoint"]}
self.assertTrue(validator({}, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
# admin and users presented in deployment
mock_deploy_get.return_value = {"admin": "a", "users": ["u1", "h2"]}
self.assertTrue(validator({}, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
# admin and user context
mock_deploy_get.return_value = {"admin": "a", "users": []}
context = {"context": {"users": True}}
self.assertTrue(validator(context, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
# just admin presented
mock_deploy_get.return_value = {"admin": "a", "users": []}
self.assertFalse(validator({}, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
@mock.patch("rally.benchmark.validation.objects.Deployment.get")
def test_required_openstack_with_admin_and_users(self, mock_deploy_get):
validator = self._unwrap_validator(validation.required_openstack,
admin=True, users=True)
task = {"deployment_uuid": mock.MagicMock()}
mock_deploy_get.return_value = {"admin": "a", "users": []}
self.assertFalse(validator({}, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
mock_deploy_get.return_value = {"admin": "a", "users": ["u"]}
self.assertTrue(validator({}, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
mock_deploy_get.reset_mock()
# admin and user context
mock_deploy_get.return_value = {"admin": "a", "users": []}
context = {"context": {"users": True}}
self.assertTrue(validator(context, None, task).is_valid)
mock_deploy_get.assert_called_once_with(task["deployment_uuid"])
def test_required_openstack_invalid(self):
validator = self._unwrap_validator(validation.required_openstack)
self.assertFalse(validator(None, None, None).is_valid)