Use cls instances instead of object in benchmarks

Using @classmethod as a base for scenarios was actually caused
by historical reasons (of using pytest as a base for benchmarks)
As we don't use it anymore (for a long time) we are able to simplify
benchmark framework and use cls instances and plain methods.

This is only the first step. That just make required changes and fix
unit tests. In next patchset I will refactor & clean exisitng unit tests.

blueprint refactor-scenarios-to-use-class-instances

Change-Id: Idd270635f70731ccf575174f8f96dc1e95cc0f8a
This commit is contained in:
Boris Pavlovic
2014-01-23 11:36:30 +04:00
parent d41a5cea37
commit a4e906dcfc
15 changed files with 461 additions and 534 deletions

View File

@@ -28,6 +28,12 @@ class Scenario(object):
""" """
registred = False registred = False
def __init__(self, context=None, admin_clients=None, clients=None):
self._context = context
self._admin_clients = admin_clients
self._clients = clients
self._idle_time = 0
@staticmethod @staticmethod
def register(): def register():
if not Scenario.registred: if not Scenario.registred:
@@ -74,18 +80,16 @@ class Scenario(object):
def cleanup(cls): def cleanup(cls):
"""This method should free all allocated resources.""" """This method should free all allocated resources."""
@classmethod def context(self):
def context(cls):
"""Returns the context of the current benchmark scenario. """Returns the context of the current benchmark scenario.
The context is the return value of the init() class. The context is the return value of the init() class.
:returns: Dict :returns: Dict
""" """
return cls._context return self._context
@classmethod def clients(self, client_type):
def clients(cls, client_type):
"""Returns a python openstack client of the requested type. """Returns a python openstack client of the requested type.
The client will be that for one of the temporary non-administrator The client will be that for one of the temporary non-administrator
@@ -95,24 +99,22 @@ class Scenario(object):
:returns: Python openstack client object :returns: Python openstack client object
""" """
return cls._clients[client_type] return self._clients[client_type]
@classmethod def admin_clients(self, client_type):
def admin_clients(cls, client_type):
"""Returns a python admin openstack client of the requested type. """Returns a python admin openstack client of the requested type.
:param client_type: Client type ("nova"/"glance" etc.) :param client_type: Client type ("nova"/"glance" etc.)
:returns: Python openstack client object :returns: Python openstack client object
""" """
return cls._admin_clients[client_type] return self._admin_clients[client_type]
@classmethod def sleep_between(self, min_sleep, max_sleep):
def sleep_between(cls, min_sleep, max_sleep):
"""Performs a time.sleep() call for a random amount of seconds. """Performs a time.sleep() call for a random amount of seconds.
The exact time is chosen uniformly randomly from the interval The exact time is chosen uniformly randomly from the interval
[min_sleep; max_sleep). The method also updates the idle_time class [min_sleep; max_sleep). The method also updates the idle_time
variable to take into account the overall time spent on sleeping. variable to take into account the overall time spent on sleeping.
:param min_sleep: Minimum sleep time in seconds (non-negative) :param min_sleep: Minimum sleep time in seconds (non-negative)
@@ -124,4 +126,8 @@ class Scenario(object):
sleep_time = random.uniform(min_sleep, max_sleep) sleep_time = random.uniform(min_sleep, max_sleep)
time.sleep(sleep_time) time.sleep(sleep_time)
cls.idle_time += sleep_time self._idle_time += sleep_time
def idle_time(self):
"""Returns duration of all sleep_between."""
return self._idle_time

View File

@@ -42,24 +42,20 @@ def _run_scenario_loop(args):
LOG.info("ITER: %s" % i) LOG.info("ITER: %s" % i)
# NOTE(msdubov): Each scenario run uses a random openstack client scenario = cls(context=__scenario_context__,
# from a predefined set to act from different users. admin_clients=__admin_clients__,
cls._clients = random.choice(__openstack_clients__) clients=random.choice(__openstack_clients__))
cls._admin_clients = __admin_clients__
cls._context = __scenario_context__
cls.idle_time = 0
try: try:
scenario_output = None scenario_output = None
with rutils.Timer() as timer: with rutils.Timer() as timer:
scenario_output = getattr(cls, method_name)(**kwargs) scenario_output = getattr(scenario, method_name)(**kwargs)
error = None error = None
except Exception as e: except Exception as e:
error = utils.format_exc(e) error = utils.format_exc(e)
finally: finally:
return {"time": timer.duration() - cls.idle_time, return {"time": timer.duration() - scenario.idle_time(),
"idle_time": cls.idle_time, "error": error, "idle_time": scenario.idle_time(), "error": error,
"scenario_output": scenario_output} "scenario_output": scenario_output}

View File

@@ -37,8 +37,7 @@ def generate_volume_name(length=10):
class CinderScenario(base.Scenario): class CinderScenario(base.Scenario):
@classmethod def _create_volume(self, size, **kwargs):
def _create_volume(cls, size, **kwargs):
"""create one volume. """create one volume.
Returns when the volume is actually created and is in the "Available" Returns when the volume is actually created and is in the "Available"
@@ -51,7 +50,7 @@ class CinderScenario(base.Scenario):
""" """
volumename = kwargs.get('display_name', generate_volume_name(10)) volumename = kwargs.get('display_name', generate_volume_name(10))
kwargs['display_name'] = volumename kwargs['display_name'] = volumename
volume = cls.clients("cinder").volumes.create(size, **kwargs) volume = self.clients("cinder").volumes.create(size, **kwargs)
# NOTE(msdubov): It is reasonable to wait 5 secs before starting to # NOTE(msdubov): It is reasonable to wait 5 secs before starting to
# check whether the volume is ready => less API calls. # check whether the volume is ready => less API calls.
time.sleep(3) time.sleep(3)
@@ -61,8 +60,7 @@ class CinderScenario(base.Scenario):
timeout=600, check_interval=3) timeout=600, check_interval=3)
return volume return volume
@classmethod def _delete_volume(self, volume):
def _delete_volume(cls, volume):
"""Delete the given volume. """Delete the given volume.
Returns when the volume is actually deleted. Returns when the volume is actually deleted.

View File

@@ -18,15 +18,21 @@ from rally.benchmark.scenarios.cinder import utils
class CinderVolumes(utils.CinderScenario): class CinderVolumes(utils.CinderScenario):
@classmethod def create_and_delete_volume(self, size, min_sleep=0, max_sleep=0,
def create_and_delete_volume(cls, size, **kwargs):
min_sleep=0, max_sleep=0, **kwargs): """Tests creating and then deleting a volume.
"""Tests creating and then deleting a volume."""
volume = cls._create_volume(size, **kwargs) Good for testing a maximal bandwith of cloud.
cls.sleep_between(min_sleep, max_sleep) """
cls._delete_volume(volume)
@classmethod volume = self._create_volume(size, **kwargs)
def create_volume(cls, size, **kwargs): self.sleep_between(min_sleep, max_sleep)
cls._create_volume(size, **kwargs) self._delete_volume(volume)
def create_volume(self, size, **kwargs):
"""Test creating volumes perfromance.
Good test to check how influence amount of active volumes on
performance of creating new.
"""
self._create_volume(size, **kwargs)

View File

@@ -18,11 +18,9 @@ from rally.benchmark.scenarios.keystone import utils as kutils
class KeystoneBasic(kutils.KeystoneScenario): class KeystoneBasic(kutils.KeystoneScenario):
@classmethod def create_user(self, name_length=10, **kwargs):
def create_user(cls, name_length=10, **kwargs): self._user_create(name_length=name_length, **kwargs)
cls._user_create(name_length=name_length, **kwargs)
@classmethod def create_delete_user(self, name_length=10, **kwargs):
def create_delete_user(cls, name_length=10, **kwargs): user = self._user_create(name_length=name_length, **kwargs)
user = cls._user_create(name_length=name_length, **kwargs) self._resource_delete(user)
cls._resource_delete(user)

View File

@@ -37,8 +37,8 @@ class KeystoneScenario(base.Scenario):
most of them are creating/deleting resources. most of them are creating/deleting resources.
""" """
@classmethod def _user_create(self, name_length=10, password=None, email=None,
def _user_create(cls, name_length=10, password=None, email=None, **kwargs): **kwargs):
"""Creates keystone user with random name. """Creates keystone user with random name.
:param name_length: length of generated (ranodm) part of name :param name_length: length of generated (ranodm) part of name
@@ -52,10 +52,9 @@ class KeystoneScenario(base.Scenario):
# when we switch to v3. # when we switch to v3.
password = password or name password = password or name
email = email or (name + "@rally.me") email = email or (name + "@rally.me")
return cls.admin_clients("keystone").users.create(name, password, return self.admin_clients("keystone").users.create(name, password,
email, **kwargs) email, **kwargs)
@classmethod def _resource_delete(self, resource):
def _resource_delete(cls, resource):
""""Delete keystone resource.""" """"Delete keystone resource."""
resource.delete() resource.delete()

View File

@@ -28,40 +28,37 @@ from rally import sshutils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
ACTION_BUILDER = scenario_utils.ActionBuilder(
['hard_reboot', 'soft_reboot', 'stop_start', 'rescue_unrescue'])
class NovaServers(utils.NovaScenario, class NovaServers(utils.NovaScenario,
cinder_utils.CinderScenario): cinder_utils.CinderScenario):
@classmethod def __init__(self, *args, **kwargs):
def boot_and_delete_server(cls, image_id, flavor_id, super(NovaServers, self).__init__(*args, **kwargs)
def boot_and_delete_server(self, image_id, flavor_id,
min_sleep=0, max_sleep=0, **kwargs): min_sleep=0, max_sleep=0, **kwargs):
"""Tests booting and then deleting an image.""" """Tests booting and then deleting an image."""
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
server = cls._boot_server(server_name, image_id, flavor_id, **kwargs) server = self._boot_server(server_name, image_id, flavor_id, **kwargs)
cls.sleep_between(min_sleep, max_sleep) self.sleep_between(min_sleep, max_sleep)
cls._delete_server(server) self._delete_server(server)
@classmethod def boot_server_from_volume_and_delete(self, image_id, flavor_id,
def boot_server_from_volume_and_delete(cls, image_id, flavor_id,
volume_size, volume_size,
min_sleep=0, max_sleep=0, **kwargs): min_sleep=0, max_sleep=0, **kwargs):
"""Tests booting from volume and then deleting an image and volume.""" """Tests booting from volume and then deleting an image and volume."""
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
volume = cls._create_volume(volume_size, imageRef=image_id) volume = self._create_volume(volume_size, imageRef=image_id)
block_device_mapping = {'vda': '%s:::1' % volume.id} block_device_mapping = {'vda': '%s:::1' % volume.id}
server = cls._boot_server(server_name, image_id, flavor_id, server = self._boot_server(server_name, image_id, flavor_id,
block_device_mapping=block_device_mapping, block_device_mapping=block_device_mapping,
**kwargs) **kwargs)
cls.sleep_between(min_sleep, max_sleep) self.sleep_between(min_sleep, max_sleep)
cls._delete_server(server) self._delete_server(server)
@classmethod def boot_runcommand_delete_server(self, image_id, flavor_id,
def boot_runcommand_delete_server(cls, image_id, flavor_id,
script, interpreter, network='private', script, interpreter, network='private',
username='ubuntu', ip_version=4, username='ubuntu', ip_version=4,
retries=60, port=22, **kwargs): retries=60, port=22, **kwargs):
@@ -81,9 +78,9 @@ class NovaServers(utils.NovaScenario,
Example Script in doc/samples/support/instance_dd_test.sh Example Script in doc/samples/support/instance_dd_test.sh
""" """
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
server = cls._boot_server(server_name, image_id, flavor_id, server = self._boot_server(server_name, image_id, flavor_id,
key_name='rally_ssh_key', **kwargs) key_name='rally_ssh_key', **kwargs)
if network not in server.addresses: if network not in server.addresses:
@@ -99,7 +96,7 @@ class NovaServers(utils.NovaScenario,
server_ip = [ip for ip in server.addresses[network] if server_ip = [ip for ip in server.addresses[network] if
ip['version'] == ip_version][0]['addr'] ip['version'] == ip_version][0]['addr']
ssh = sshutils.SSH(ip=server_ip, port=port, user=username, ssh = sshutils.SSH(ip=server_ip, port=port, user=username,
key=cls.clients('ssh_key_pair')['private'], key=self.clients('ssh_key_pair')['private'],
key_type='string') key_type='string')
for retry in range(retries): for retry in range(retries):
@@ -123,12 +120,12 @@ class NovaServers(utils.NovaScenario,
'Error: %(error)s') % dict( 'Error: %(error)s') % dict(
id=server.id, ip=server_ip, retry=retry, id=server.id, ip=server_ip, retry=retry,
error=benchmark_utils.format_exc(e))) error=benchmark_utils.format_exc(e)))
cls.sleep_between(5, 5) self.sleep_between(5, 5)
except ValueError: except ValueError:
LOG.error(_('Script %(script)s did not output valid JSON. ') LOG.error(_('Script %(script)s did not output valid JSON. ')
% dict(script=script)) % dict(script=script))
cls._delete_server(server) self._delete_server(server)
LOG.debug(_('Output streams from in-instance script execution: ' LOG.debug(_('Output streams from in-instance script execution: '
'stdout: %(stdout)s, stderr: $(stderr)s') % dict( 'stdout: %(stdout)s, stderr: $(stderr)s') % dict(
stdout=str(streams[sshutils.SSH.STDOUT_INDEX]), stdout=str(streams[sshutils.SSH.STDOUT_INDEX]),
@@ -136,66 +133,76 @@ class NovaServers(utils.NovaScenario,
return dict(data=streams[sshutils.SSH.STDOUT_INDEX], return dict(data=streams[sshutils.SSH.STDOUT_INDEX],
errors=streams[sshutils.SSH.STDERR_INDEX]) errors=streams[sshutils.SSH.STDERR_INDEX])
@classmethod def boot_and_bounce_server(self, image_id, flavor_id, **kwargs):
def boot_and_bounce_server(cls, image_id, flavor_id, **kwargs):
"""Tests booting a server then performing stop/start or hard/soft """Tests booting a server then performing stop/start or hard/soft
reboot a number of times. reboot a number of times.
""" """
action_builder = self._bind_actions()
actions = kwargs.get('actions', []) actions = kwargs.get('actions', [])
try: try:
ACTION_BUILDER.validate(actions) action_builder.validate(actions)
except jsonschema.exceptions.ValidationError as error: except jsonschema.exceptions.ValidationError as error:
raise rally_exceptions.InvalidConfigException( raise rally_exceptions.InvalidConfigException(
"Invalid server actions configuration \'%(actions)s\' due to: " "Invalid server actions configuration \'%(actions)s\' due to: "
"%(error)s" % {'actions': str(actions), 'error': str(error)}) "%(error)s" % {'actions': str(actions), 'error': str(error)})
server = cls._boot_server(cls._generate_random_name(16), server = self._boot_server(self._generate_random_name(16),
image_id, flavor_id, **kwargs) image_id, flavor_id, **kwargs)
for action in ACTION_BUILDER.build_actions(actions, server): for action in action_builder.build_actions(actions, server):
action() action()
cls._delete_server(server) self._delete_server(server)
@classmethod def snapshot_server(self, image_id, flavor_id, **kwargs):
def snapshot_server(cls, image_id, flavor_id, **kwargs):
"""Tests Nova instance snapshotting.""" """Tests Nova instance snapshotting."""
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
server = cls._boot_server(server_name, image_id, flavor_id, **kwargs) server = self._boot_server(server_name, image_id, flavor_id, **kwargs)
image = cls._create_image(server) image = self._create_image(server)
cls._delete_server(server) self._delete_server(server)
server = cls._boot_server(server_name, image.id, flavor_id, **kwargs) server = self._boot_server(server_name, image.id, flavor_id, **kwargs)
cls._delete_server(server) self._delete_server(server)
cls._delete_image(image) self._delete_image(image)
@classmethod def boot_server(self, image_id, flavor_id, **kwargs):
def boot_server(cls, image_id, flavor_id, **kwargs):
"""Test VM boot - assumed clean-up is done elsewhere.""" """Test VM boot - assumed clean-up is done elsewhere."""
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
if 'nics' not in kwargs: if 'nics' not in kwargs:
nets = cls.clients("nova").networks.list() nets = self.clients("nova").networks.list()
if nets: if nets:
random_nic = random.choice(nets) random_nic = random.choice(nets)
kwargs['nics'] = [{'net-id': random_nic.id}] kwargs['nics'] = [{'net-id': random_nic.id}]
cls._boot_server(server_name, image_id, flavor_id, **kwargs) self._boot_server(server_name, image_id, flavor_id, **kwargs)
@classmethod def boot_server_from_volume(self, image_id, flavor_id,
def boot_server_from_volume(cls, image_id, flavor_id,
volume_size, **kwargs): volume_size, **kwargs):
"""Test VM boot from volume - assumed clean-up is done elsewhere.""" """Test VM boot from volume - assumed clean-up is done elsewhere."""
server_name = cls._generate_random_name(16) server_name = self._generate_random_name(16)
if 'nics' not in kwargs: if 'nics' not in kwargs:
nets = cls.clients("nova").networks.list() nets = self.clients("nova").networks.list()
if nets: if nets:
random_nic = random.choice(nets) random_nic = random.choice(nets)
kwargs['nics'] = [{'net-id': random_nic.id}] kwargs['nics'] = [{'net-id': random_nic.id}]
volume = cls._create_volume(volume_size, imageRef=image_id) volume = self._create_volume(volume_size, imageRef=image_id)
block_device_mapping = {'vda': '%s:::1' % volume.id} block_device_mapping = {'vda': '%s:::1' % volume.id}
cls._boot_server(server_name, image_id, flavor_id, self._boot_server(server_name, image_id, flavor_id,
block_device_mapping=block_device_mapping, block_device_mapping=block_device_mapping,
**kwargs) **kwargs)
@classmethod def _bind_actions(self):
def _stop_and_start_server(cls, server): actions = ['hard_reboot', 'soft_reboot', 'stop_start',
'rescue_unrescue']
action_builder = scenario_utils.ActionBuilder(actions)
action_builder.bind_action('hard_reboot', self._reboot_server,
soft=False)
action_builder.bind_action('soft_reboot', self._reboot_server,
soft=True)
action_builder.bind_action('stop_start',
self._stop_and_start_server)
action_builder.bind_action('rescue_unrescue',
self._rescue_and_unrescue_server)
return action_builder
def _stop_and_start_server(self, server):
"""Stop and then start the given server. """Stop and then start the given server.
A stop will be issued on the given server upon which time A stop will be issued on the given server upon which time
@@ -206,11 +213,10 @@ class NovaServers(utils.NovaScenario,
:param server: The server to stop and then start. :param server: The server to stop and then start.
""" """
cls._stop_server(server) self._stop_server(server)
cls._start_server(server) self._start_server(server)
@classmethod def _rescue_and_unrescue_server(self, server):
def _rescue_and_unrescue_server(cls, server):
"""Rescue and then unrescue the given server. """Rescue and then unrescue the given server.
A rescue will be issued on the given server upon which time A rescue will be issued on the given server upon which time
this method will wait for the server to become 'RESCUE'. this method will wait for the server to become 'RESCUE'.
@@ -221,15 +227,5 @@ class NovaServers(utils.NovaScenario,
:param server: The server to rescue and then unrescue. :param server: The server to rescue and then unrescue.
""" """
cls._rescue_server(server) self._rescue_server(server)
cls._unrescue_server(server) self._unrescue_server(server)
ACTION_BUILDER.bind_action('hard_reboot',
utils.NovaScenario._reboot_server, soft=False)
ACTION_BUILDER.bind_action('soft_reboot',
utils.NovaScenario._reboot_server, soft=True)
ACTION_BUILDER.bind_action('stop_start',
NovaServers._stop_and_start_server)
ACTION_BUILDER.bind_action('rescue_unrescue',
NovaServers._rescue_and_unrescue_server)

View File

@@ -24,8 +24,7 @@ from rally import utils
class NovaScenario(base.Scenario): class NovaScenario(base.Scenario):
@classmethod def _boot_server(self, server_name, image_id, flavor_id, **kwargs):
def _boot_server(cls, server_name, image_id, flavor_id, **kwargs):
"""Boots one server. """Boots one server.
Returns when the server is actually booted and is in the "Active" Returns when the server is actually booted and is in the "Active"
@@ -45,8 +44,8 @@ class NovaScenario(base.Scenario):
if 'rally_open' not in kwargs['security_groups']: if 'rally_open' not in kwargs['security_groups']:
kwargs['security_groups'].append('rally_open') kwargs['security_groups'].append('rally_open')
server = cls.clients("nova").servers.create( server = self.clients("nova").servers.create(server_name, image_id,
server_name, image_id, flavor_id, **kwargs) flavor_id, **kwargs)
# NOTE(msdubov): It is reasonable to wait 5 secs before starting to # NOTE(msdubov): It is reasonable to wait 5 secs before starting to
# check whether the server is ready => less API calls. # check whether the server is ready => less API calls.
time.sleep(5) time.sleep(5)
@@ -56,8 +55,7 @@ class NovaScenario(base.Scenario):
timeout=600, check_interval=3) timeout=600, check_interval=3)
return server return server
@classmethod def _reboot_server(self, server, soft=True):
def _reboot_server(cls, server, soft=True):
"""Reboots the given server using hard or soft reboot. """Reboots the given server using hard or soft reboot.
A reboot will be issued on the given server upon which time A reboot will be issued on the given server upon which time
@@ -73,8 +71,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _start_server(self, server):
def _start_server(cls, server):
"""Starts the given server. """Starts the given server.
A start will be issued for the given server upon which time A start will be issued for the given server upon which time
@@ -87,8 +84,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=2) timeout=600, check_interval=2)
@classmethod def _stop_server(self, server):
def _stop_server(cls, server):
"""Stop the given server. """Stop the given server.
Issues a stop on the given server and waits for the server Issues a stop on the given server and waits for the server
@@ -101,8 +97,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=2) timeout=600, check_interval=2)
@classmethod def _rescue_server(self, server):
def _rescue_server(cls, server):
"""Rescue the given server. """Rescue the given server.
Returns when the server is actually rescue and is in the "Rescue" Returns when the server is actually rescue and is in the "Rescue"
@@ -116,8 +111,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _unrescue_server(self, server):
def _unrescue_server(cls, server):
"""Unrescue the given server. """Unrescue the given server.
Returns when the server is unrescue and waits to become ACTIVE Returns when the server is unrescue and waits to become ACTIVE
@@ -130,8 +124,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _suspend_server(self, server):
def _suspend_server(cls, server):
"""Suspends the given server. """Suspends the given server.
Returns when the server is actually suspended and is in the "Suspended" Returns when the server is actually suspended and is in the "Suspended"
@@ -145,8 +138,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _delete_server(self, server):
def _delete_server(cls, server):
"""Deletes the given server. """Deletes the given server.
Returns when the server is actually deleted. Returns when the server is actually deleted.
@@ -158,15 +150,13 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _delete_all_servers(self):
def _delete_all_servers(cls):
"""Deletes all servers in current tenant.""" """Deletes all servers in current tenant."""
servers = cls.clients("nova").servers.list() servers = self.clients("nova").servers.list()
for server in servers: for server in servers:
cls._delete_server(server) self._delete_server(server)
@classmethod def _delete_image(self, image):
def _delete_image(cls, image):
"""Deletes the given image. """Deletes the given image.
Returns when the image is actually deleted. Returns when the image is actually deleted.
@@ -178,8 +168,7 @@ class NovaScenario(base.Scenario):
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
@classmethod def _create_image(self, server):
def _create_image(cls, server):
"""Creates an image of the given server """Creates an image of the given server
Uses the server name to name the created image. Returns when the image Uses the server name to name the created image. Returns when the image
@@ -189,18 +178,17 @@ class NovaScenario(base.Scenario):
:returns: Created image object :returns: Created image object
""" """
image_uuid = cls.clients("nova").servers.create_image(server, image_uuid = self.clients("nova").servers.create_image(server,
server.name) server.name)
image = cls.clients("nova").images.get(image_uuid) image = self.clients("nova").images.get(image_uuid)
image = utils.wait_for(image, image = utils.wait_for(image,
is_ready=bench_utils.resource_is("ACTIVE"), is_ready=bench_utils.resource_is("ACTIVE"),
update_resource=bench_utils.get_from_manager(), update_resource=bench_utils.get_from_manager(),
timeout=600, check_interval=3) timeout=600, check_interval=3)
return image return image
@classmethod def _boot_servers(self, name_prefix, image_id, flavor_id,
def _boot_servers(cls, name_prefix, image_id, flavor_id, requests, instances_amount=1, **kwargs):
requests, instances_per_request=1, **kwargs):
"""Boots multiple servers. """Boots multiple servers.
Returns when all the servers are actually booted and are in the Returns when all the servers are actually booted and are in the
@@ -211,22 +199,21 @@ class NovaScenario(base.Scenario):
:param image_id: ID of the image to be used for server creation :param image_id: ID of the image to be used for server creation
:param flavor_id: ID of the flavor to be used for server creation :param flavor_id: ID of the flavor to be used for server creation
:param requests: Number of booting requests to perform :param requests: Number of booting requests to perform
:param instances_per_request: Number of instances to boot :param instances_amount: Number of instances to boot per each request
per each request
:returns: List of created server objects :returns: List of created server objects
""" """
for i in range(requests): for i in range(requests):
cls.clients("nova").servers.create('%s_%d' % (name_prefix, i), self.clients("nova").servers.create('%s_%d' % (name_prefix, i),
image_id, flavor_id, image_id, flavor_id,
min_count=instances_per_request, min_count=instances_amount,
max_count=instances_per_request, max_count=instances_amount,
**kwargs) **kwargs)
# NOTE(msdubov): Nova python client returns only one server even when # NOTE(msdubov): Nova python client returns only one server even when
# min_count > 1, so we have to rediscover all the # min_count > 1, so we have to rediscover all the
# created servers manyally. # created servers manyally.
servers = filter(lambda server: server.name.startswith(name_prefix), servers = filter(lambda server: server.name.startswith(name_prefix),
cls.clients("nova").servers.list()) self.clients("nova").servers.list())
time.sleep(5) time.sleep(5)
servers = [utils.wait_for(server, servers = [utils.wait_for(server,
is_ready=bench_utils.resource_is("ACTIVE"), is_ready=bench_utils.resource_is("ACTIVE"),
@@ -236,6 +223,5 @@ class NovaScenario(base.Scenario):
for server in servers] for server in servers]
return servers return servers
@classmethod def _generate_random_name(self, length):
def _generate_random_name(cls, length):
return ''.join(random.choice(string.lowercase) for i in range(length)) return ''.join(random.choice(string.lowercase) for i in range(length))

View File

@@ -24,19 +24,24 @@ CINDER_VOLUMES = "rally.benchmark.scenarios.cinder.volumes.CinderVolumes"
class CinderServersTestCase(test.TestCase): class CinderServersTestCase(test.TestCase):
@mock.patch(CINDER_VOLUMES + ".sleep_between")
@mock.patch(CINDER_VOLUMES + "._delete_volume")
@mock.patch(CINDER_VOLUMES + "._create_volume")
def _verify_create_and_delete_volume(self, mock_create, mock_delete,
mock_sleep):
fake_volume = object()
mock_create.return_value = fake_volume
volumes.CinderVolumes.create_and_delete_volume(1, 10, 20,
fakearg="f")
mock_create.assert_called_once_with(1, fakearg="f")
mock_sleep.assert_called_once_with(10, 20)
mock_delete.assert_called_once_with(fake_volume)
def test_create_and_delete_volume(self): def test_create_and_delete_volume(self):
self._verify_create_and_delete_volume() fake_volume = mock.MagicMock()
scenario = volumes.CinderVolumes()
scenario._create_volume = mock.MagicMock(return_value=fake_volume)
scenario.sleep_between = mock.MagicMock()
scenario._delete_volume = mock.MagicMock()
scenario.create_and_delete_volume(1, 10, 20, fakearg="f")
scenario._create_volume.assert_called_once_with(1, fakearg="f")
scenario.sleep_between.assert_called_once_with(10, 20)
scenario._delete_volume.assert_called_once_with(fake_volume)
def test_create_volume(self):
fake_volume = mock.MagicMock()
scenario = volumes.CinderVolumes()
scenario._create_volume = mock.MagicMock(return_value=fake_volume)
scenario.create_volume(1, fakearg="f")
scenario._create_volume.assert_called_once_with(1, fakearg="f")

View File

@@ -27,26 +27,29 @@ KEYSTONE_UTILS = KEYSTONE_BASE + "utils."
class KeystoneBasicTestCase(test.TestCase): class KeystoneBasicTestCase(test.TestCase):
@mock.patch(KEYSTONE_UTILS + "generate_keystone_name") @mock.patch(KEYSTONE_UTILS + "generate_keystone_name")
@mock.patch(KEYSTONE_BASIC + "_user_create") def test_create_user(self, mock_gen_name):
def test_create_user(self, mock_create, mock_gen_name): scenario = basic.KeystoneBasic()
mock_gen_name.return_value = "teeeest" mock_gen_name.return_value = "teeeest"
basic.KeystoneBasic.create_user(name_length=20, password="tttt", scenario._user_create = mock.MagicMock()
scenario.create_user(name_length=20, password="tttt",
**{"tenant_id": "id"}) **{"tenant_id": "id"})
scenario._user_create.assert_called_once_with(name_length=20,
mock_create.assert_called_once_with(name_length=20, password="tttt", password="tttt",
**{"tenant_id": "id"}) **{"tenant_id": "id"})
@mock.patch(KEYSTONE_UTILS + "generate_keystone_name") @mock.patch(KEYSTONE_UTILS + "generate_keystone_name")
@mock.patch(KEYSTONE_BASIC + "_resource_delete") def test_create_delete_user(self, mock_gen_name):
@mock.patch(KEYSTONE_BASIC + "_user_create") create_result = mock.MagicMock()
def test_create_delete_user(self, mock_create, mock_delete, mock_gen_name):
create_result = {} scenario = basic.KeystoneBasic()
mock_create.return_value = create_result scenario._user_create = mock.MagicMock(return_value=create_result)
scenario._resource_delete = mock.MagicMock()
mock_gen_name.return_value = "teeeest" mock_gen_name.return_value = "teeeest"
basic.KeystoneBasic.create_delete_user(name_length=30, email="abcd", scenario.create_delete_user(name_length=30, email="abcd",
**{"enabled": True}) **{"enabled": True})
mock_create.assert_called_once_with(name_length=30, email="abcd", scenario._user_create.assert_called_once_with(name_length=30,
email="abcd",
**{"enabled": True}) **{"enabled": True})
mock_delete.assert_called_once_with(create_result) scenario._resource_delete.assert_called_once_with(create_result)

View File

@@ -47,21 +47,20 @@ class KeystoneUtilsTestCase(test.TestCase):
class KeystoneScenarioTestCase(test.TestCase): class KeystoneScenarioTestCase(test.TestCase):
@mock.patch(UTILS + "KeystoneScenario.admin_clients")
@mock.patch(UTILS + "generate_keystone_name") @mock.patch(UTILS + "generate_keystone_name")
def test_user_create(self, mock_gen_name, mock_admin_clients): def test_user_create(self, mock_gen_name):
name = "abc" name = "abc"
mock_gen_name.return_value = name mock_gen_name.return_value = name
user = {} user = {}
fake_keystone = fakes.FakeKeystoneClient() fake_keystone = fakes.FakeKeystoneClient()
fake_keystone.users.create = mock.MagicMock(return_value=user) fake_keystone.users.create = mock.MagicMock(return_value=user)
mock_admin_clients.return_value = fake_keystone scenario = utils.KeystoneScenario(
admin_clients={"keystone": fake_keystone})
result = utils.KeystoneScenario._user_create() result = scenario._user_create()
self.assertEqual(user, result) self.assertEqual(user, result)
mock_admin_clients.assert_called_once_with("keystone")
fake_keystone.users.create.assert_called_once_with(name, name, fake_keystone.users.create.assert_called_once_with(name, name,
name + "@rally.me") name + "@rally.me")
@@ -69,5 +68,5 @@ class KeystoneScenarioTestCase(test.TestCase):
resource = fakes.FakeResource() resource = fakes.FakeResource()
resource.delete = mock.MagicMock() resource.delete = mock.MagicMock()
utils.KeystoneScenario._resource_delete(resource) utils.KeystoneScenario()._resource_delete(resource)
resource.delete.assert_called_once_with() resource.delete.assert_called_once_with()

View File

@@ -27,60 +27,12 @@ NOVA_SERVERS = "rally.benchmark.scenarios.nova.servers.NovaServers"
class NovaServersTestCase(test.TestCase): class NovaServersTestCase(test.TestCase):
@mock.patch(NOVA_SERVERS + ".sleep_between")
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
def _verify_boot_and_delete_server(self, mock_boot, mock_delete,
mock_random_name, mock_sleep):
fake_server = object()
mock_boot.return_value = fake_server
mock_random_name.return_value = "random_name"
servers.NovaServers.boot_and_delete_server("img", 0, 10, 20,
fakearg="f")
mock_boot.assert_called_once_with("random_name", "img", 0, fakearg="f")
mock_sleep.assert_called_once_with(10, 20)
mock_delete.assert_called_once_with(fake_server)
@mock.patch(NOVA_SERVERS + ".sleep_between")
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
@mock.patch(NOVA_SERVERS + "._create_volume")
def _verify_boot_server_from_volume_and_delete(self, mock_volume,
mock_boot, mock_delete,
mock_random_name,
mock_sleep):
fake_server = object()
mock_boot.return_value = fake_server
mock_random_name.return_value = "random_name"
fake_volume = fakes.FakeVolumeManager().create()
fake_volume.id = "volume_id"
mock_volume.return_value = fake_volume
servers.NovaServers.boot_server_from_volume_and_delete("img", 0, 5,
10, 20,
fakearg="f")
mock_volume.assert_called_once_with(5, imageRef="img")
mock_boot.assert_called_once_with(
"random_name", "img", 0,
block_device_mapping={'vda': 'volume_id:::1'},
fakearg="f")
mock_sleep.assert_called_once_with(10, 20)
mock_delete.assert_called_once_with(fake_server)
@mock.patch("json.loads") @mock.patch("json.loads")
@mock.patch("rally.benchmark.base.Scenario.clients") @mock.patch("rally.benchmark.base.Scenario.clients")
@mock.patch("rally.sshutils.SSH.execute_script") @mock.patch("rally.sshutils.SSH.execute_script")
@mock.patch(NOVA_SERVERS + ".sleep_between") def _verify_boot_runcommand_delete_server(self, mock_ssh_execute_script,
@mock.patch(NOVA_SERVERS + "._generate_random_name") mock_base_clients,
@mock.patch(NOVA_SERVERS + "._delete_server") mock_json_loads):
@mock.patch(NOVA_SERVERS + "._boot_server")
def _verify_boot_runcommand_delete_server(
self, mock_boot, mock_delete, mock_random_name, mock_sleep,
mock_ssh_execute_script, mock_base_clients, mock_json_loads):
fake_server = fakes.FakeServer() fake_server = fakes.FakeServer()
fake_server.addresses = dict( fake_server.addresses = dict(
private=[dict( private=[dict(
@@ -88,243 +40,158 @@ class NovaServersTestCase(test.TestCase):
addr="1.2.3.4" addr="1.2.3.4"
)] )]
) )
mock_boot.return_value = fake_server scenario = servers.NovaServers()
mock_random_name.return_value = "random_name"
scenario._boot_server = mock.MagicMock(return_value=fake_server)
scenario._generate_random_name = mock.MagicMock(return_value="name")
scenario._delete_server = mock.MagicMock()
mock_ssh_execute_script.return_value = ('stdout', 'stderr') mock_ssh_execute_script.return_value = ('stdout', 'stderr')
mock_base_clients.return_value = dict(private='private-key-string') mock_base_clients.return_value = dict(private='private-key-string')
servers.NovaServers.boot_runcommand_delete_server( scenario.boot_runcommand_delete_server("img", 0, "script_path",
"img", 0, "script_path", "/bin/bash", fakearg="f") "/bin/bash", fakearg="f")
mock_boot.assert_called_once_with( scenario._boot_server.assert_called_once_with("name", "img", 0,
"random_name", "img", 0, fakearg="f", key_name='rally_ssh_key') fakearg="f",
key_name='rally_ssh_key')
mock_ssh_execute_script.assert_called_once_with( mock_ssh_execute_script.assert_called_once_with(
script="script_path", script="script_path", interpreter="/bin/bash", get_stdout=True,
interpreter="/bin/bash", get_stderr=True)
get_stdout=True,
get_stderr=True
)
mock_json_loads.assert_called_once_with('stdout') mock_json_loads.assert_called_once_with('stdout')
mock_delete.assert_called_once_with(fake_server) scenario._delete_server.assert_called_once_with(fake_server)
fake_server.addresses = {} fake_server.addresses = {}
self.assertRaises( self.assertRaises(
ValueError, ValueError,
servers.NovaServers.boot_runcommand_delete_server, scenario.boot_runcommand_delete_server,
"img", 0, "script_path", "/bin/bash", "img", 0, "script_path", "/bin/bash",
fakearg="f" fakearg="f"
) )
@mock.patch(NOVA_SERVERS + "._generate_random_name") def test_boot_rescue_unrescue(self):
@mock.patch(NOVA_SERVERS + "._boot_server")
@mock.patch("rally.benchmark.utils.osclients")
@mock.patch("rally.benchmark.scenarios.nova.servers.random.choice")
def _verify_boot_server(self, mock_choice, mock_osclients, mock_boot,
mock_random_name, nic=None, assert_nic=False):
assert_nic = nic or assert_nic
kwargs = {'fakearg': 'f'}
expected_kwargs = {'fakearg': 'f'}
fc = fakes.FakeClients()
mock_osclients.Clients.return_value = fc
nova = fakes.FakeNovaClient()
fc.get_nova_client = lambda: nova
temp_keys = ["username", "password", "tenant_name", "auth_url"]
users_endpoints = [dict(zip(temp_keys, temp_keys))]
servers.NovaServers._clients = butils.create_openstack_clients(
users_endpoints, temp_keys)[0]
mock_boot.return_value = object()
mock_random_name.return_value = "random_name"
if nic:
kwargs['nics'] = nic
if assert_nic:
nova.networks.create('net-1')
network = nova.networks.create('net-2')
mock_choice.return_value = network
expected_kwargs['nics'] = nic or [{'net-id': 'net-2'}]
servers.NovaServers.boot_server("img", 0, **kwargs)
mock_boot.assert_called_once_with("random_name", "img", 0,
**expected_kwargs)
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._boot_server")
@mock.patch("rally.benchmark.utils.osclients")
@mock.patch("rally.benchmark.scenarios.nova.servers.random.choice")
@mock.patch(NOVA_SERVERS + "._create_volume")
def _verify_boot_server_from_volume(self, mock_volume, mock_choice,
mock_osclients, mock_boot,
mock_random_name, nic=None,
assert_nic=False):
assert_nic = nic or assert_nic
kwargs = {'fakearg': 'f'}
expected_kwargs = {'fakearg': 'f'}
fc = fakes.FakeClients()
mock_osclients.Clients.return_value = fc
nova = fakes.FakeNovaClient()
fc.get_nova_client = lambda: nova
temp_keys = ["username", "password", "tenant_name", "uri"]
users_endpoints = [dict(zip(temp_keys, temp_keys))]
servers.NovaServers._clients = butils.create_openstack_clients(
users_endpoints, temp_keys)[0]
mock_boot.return_value = object()
mock_random_name.return_value = "random_name"
if nic:
kwargs['nics'] = nic
if assert_nic:
nova.networks.create('net-1')
network = nova.networks.create('net-2')
mock_choice.return_value = network
expected_kwargs['nics'] = nic or [{'net-id': 'net-2'}]
fake_volume = fakes.FakeVolumeManager().create()
fake_volume.id = "volume_id"
mock_volume.return_value = fake_volume
servers.NovaServers.boot_server_from_volume("img", 0, 5, **kwargs)
mock_volume.assert_called_once_with(5, imageRef="img")
mock_boot.assert_called_once_with(
"random_name", "img", 0,
block_device_mapping={'vda': 'volume_id:::1'},
**expected_kwargs)
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._rescue_server")
@mock.patch(NOVA_SERVERS + "._unrescue_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
def test_boot_rescue_unrescue(self, mock_boot, mock_unrescue,
mock_rescue, mock_delete, mock_name):
actions = [{'rescue_unrescue': 5}] actions = [{'rescue_unrescue': 5}]
fake_server = object() fake_server = mock.MagicMock()
mock_boot.return_value = fake_server scenario = servers.NovaServers()
mock_name.return_value = 'random_name' scenario._boot_server = mock.MagicMock(return_value=fake_server)
servers.NovaServers.boot_and_bounce_server("img", 1, scenario._generate_random_name = mock.MagicMock(return_value="name")
actions=actions) scenario._rescue_server = mock.MagicMock()
mock_boot.assert_called_once_with("random_name", "img", 1, scenario._unrescue_server = mock.MagicMock()
scenario._delete_server = mock.MagicMock()
scenario.boot_and_bounce_server("img", 1, actions=actions)
scenario._boot_server.assert_called_once_with("name", "img", 1,
actions=actions) actions=actions)
server_calls = [] server_calls = []
for i in range(5): for i in range(5):
server_calls.append(mock.call(fake_server)) server_calls.append(mock.call(fake_server))
self.assertEqual(5, mock_rescue.call_count, self.assertEqual(5, scenario._rescue_server.call_count,
"Rescue not called 5 times") "Rescue not called 5 times")
self.assertEqual(5, mock_unrescue.call_count, self.assertEqual(5, scenario._unrescue_server.call_count,
"Unrescue not called 5 times") "Unrescue not called 5 times")
mock_rescue.assert_has_calls(server_calls) scenario._rescue_server.assert_has_calls(server_calls)
mock_unrescue.assert_has_calls(server_calls) scenario._unrescue_server.assert_has_calls(server_calls)
mock_delete.assert_called_once_with(fake_server) scenario._delete_server.assert_called_once_with(fake_server)
@mock.patch(NOVA_SERVERS + "._generate_random_name") def test_boot_stop_start(self):
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._stop_server")
@mock.patch(NOVA_SERVERS + "._start_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
def test_boot_stop_start(self, mock_boot, mock_start, mock_stop,
mock_delete, mock_name):
actions = [{'stop_start': 5}] actions = [{'stop_start': 5}]
fake_server = object() fake_server = mock.MagicMock()
mock_boot.return_value = fake_server scenario = servers.NovaServers()
mock_name.return_value = 'random_name' scenario._boot_server = mock.MagicMock(return_value=fake_server)
servers.NovaServers.boot_and_bounce_server("img", 1, scenario._generate_random_name = mock.MagicMock(return_value="name")
actions=actions) scenario._start_server = mock.MagicMock()
mock_boot.assert_called_once_with("random_name", "img", 1, scenario._stop_server = mock.MagicMock()
scenario._delete_server = mock.MagicMock()
scenario.boot_and_bounce_server("img", 1, actions=actions)
scenario._boot_server.assert_called_once_with("name", "img", 1,
actions=actions) actions=actions)
server_calls = [] server_calls = []
for i in range(5): for i in range(5):
server_calls.append(mock.call(fake_server)) server_calls.append(mock.call(fake_server))
self.assertEqual(5, mock_stop.call_count, "Stop not called 5 times") self.assertEqual(5, scenario._stop_server.call_count,
self.assertEqual(5, mock_start.call_count, "Start not called 5 times") "Stop not called 5 times")
mock_stop.assert_has_calls(server_calls) self.assertEqual(5, scenario._start_server.call_count,
mock_start.assert_has_calls(server_calls) "Start not called 5 times")
mock_delete.assert_called_once_with(fake_server) scenario._stop_server.assert_has_calls(server_calls)
scenario._start_server.assert_has_calls(server_calls)
scenario._delete_server.assert_called_once_with(fake_server)
def _bind_server_actions(self, mock_reboot, mock_stop_start): def test_multiple_bounce_actions(self):
bindings = servers.ACTION_BUILDER._bindings
if mock_reboot:
bindings['soft_reboot']['action'] = mock_reboot
bindings['hard_reboot']['action'] = mock_reboot
if mock_stop_start:
bindings['stop_start']['action'] = mock_stop_start
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._reboot_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
def _verify_reboot(self, mock_boot, mock_reboot, mock_delete, mock_name,
soft=True):
actions = [{'soft_reboot' if soft else 'hard_reboot': 5}]
fake_server = object()
self._bind_server_actions(mock_reboot, None)
mock_boot.return_value = fake_server
mock_name.return_value = 'random_name'
servers.NovaServers.boot_and_bounce_server("img", 1,
actions=actions)
mock_boot.assert_called_once_with("random_name", "img", 1,
actions=actions)
server_calls = []
for i in range(5):
server_calls.append(mock.call(fake_server, soft=soft))
self.assertEqual(5, mock_reboot.call_count,
"Reboot not called 5 times")
mock_reboot.assert_has_calls(server_calls)
mock_delete.assert_called_once_with(fake_server)
@mock.patch(NOVA_SERVERS + "._generate_random_name")
@mock.patch(NOVA_SERVERS + "._delete_server")
@mock.patch(NOVA_SERVERS + "._stop_and_start_server")
@mock.patch(NOVA_SERVERS + "._reboot_server")
@mock.patch(NOVA_SERVERS + "._boot_server")
def test_multiple_bounce_actions(self, mock_boot, mock_reboot,
mock_stop_start, mock_delete, mock_name):
actions = [{'hard_reboot': 5}, {'stop_start': 8}] actions = [{'hard_reboot': 5}, {'stop_start': 8}]
fake_server = object() fake_server = mock.MagicMock()
self._bind_server_actions(mock_reboot, mock_stop_start) scenario = servers.NovaServers()
mock_boot.return_value = fake_server
mock_name.return_value = 'random_name' scenario._boot_server = mock.MagicMock(return_value=fake_server)
servers.NovaServers.boot_and_bounce_server("img", 1, scenario._delete_server = mock.MagicMock()
actions=actions) scenario._reboot_server = mock.MagicMock()
mock_boot.assert_called_once_with("random_name", "img", 1, scenario._stop_and_start_server = mock.MagicMock()
scenario._generate_random_name = mock.MagicMock(return_value='name')
scenario.boot_and_bounce_server("img", 1, actions=actions)
scenario._boot_server.assert_called_once_with("name", "img", 1,
actions=actions) actions=actions)
server_calls = [] server_calls = []
for i in range(5): for i in range(5):
server_calls.append(mock.call(fake_server, soft=False)) server_calls.append(mock.call(fake_server, soft=False))
self.assertEqual(5, mock_reboot.call_count, self.assertEqual(5, scenario._reboot_server.call_count,
"Reboot not called 5 times") "Reboot not called 5 times")
mock_reboot.assert_has_calls(server_calls) scenario._reboot_server.assert_has_calls(server_calls)
server_calls = [] server_calls = []
for i in range(8): for i in range(8):
server_calls.append(mock.call(fake_server)) server_calls.append(mock.call(fake_server))
self.assertEqual(8, mock_stop_start.call_count, self.assertEqual(8, scenario._stop_and_start_server.call_count,
"Stop/Start not called 8 times") "Stop/Start not called 8 times")
mock_stop_start.assert_has_calls(server_calls) scenario._stop_and_start_server.assert_has_calls(server_calls)
mock_delete.assert_called_once_with(fake_server) scenario._delete_server.assert_called_once_with(fake_server)
def test_validate_actions(self): def test_validate_actions(self):
actions = [{"hardd_reboot": 6}] actions = [{"hardd_reboot": 6}]
scenario = servers.NovaServers()
self.assertRaises(rally_exceptions.InvalidConfigException, self.assertRaises(rally_exceptions.InvalidConfigException,
servers.NovaServers.boot_and_bounce_server, scenario.boot_and_bounce_server,
1, 1, actions=actions) 1, 1, actions=actions)
actions = [{"hard_reboot": "no"}] actions = [{"hard_reboot": "no"}]
self.assertRaises(rally_exceptions.InvalidConfigException, self.assertRaises(rally_exceptions.InvalidConfigException,
servers.NovaServers.boot_and_bounce_server, scenario.boot_and_bounce_server,
1, 1, actions=actions) 1, 1, actions=actions)
actions = {"hard_reboot": 6} actions = {"hard_reboot": 6}
self.assertRaises(rally_exceptions.InvalidConfigException, self.assertRaises(rally_exceptions.InvalidConfigException,
servers.NovaServers.boot_and_bounce_server, scenario.boot_and_bounce_server,
1, 1, actions=actions) 1, 1, actions=actions)
actions = {"hard_reboot": -1} actions = {"hard_reboot": -1}
self.assertRaises(rally_exceptions.InvalidConfigException, self.assertRaises(rally_exceptions.InvalidConfigException,
servers.NovaServers.boot_and_bounce_server, scenario.boot_and_bounce_server,
1, 1, actions=actions) 1, 1, actions=actions)
actions = {"hard_reboot": 0} actions = {"hard_reboot": 0}
self.assertRaises(rally_exceptions.InvalidConfigException, self.assertRaises(rally_exceptions.InvalidConfigException,
servers.NovaServers.boot_and_bounce_server, scenario.boot_and_bounce_server,
1, 1, actions=actions) 1, 1, actions=actions)
def _verify_reboot(self, soft=True):
actions = [{'soft_reboot' if soft else 'hard_reboot': 5}]
fake_server = mock.MagicMock()
scenario = servers.NovaServers()
scenario._reboot_server = mock.MagicMock()
scenario._boot_server = mock.MagicMock(return_value=fake_server)
scenario._delete_server = mock.MagicMock()
scenario._generate_random_name = mock.MagicMock(return_value='name')
scenario.boot_and_bounce_server("img", 1, actions=actions)
scenario._boot_server.assert_called_once_with("name", "img", 1,
actions=actions)
server_calls = []
for i in range(5):
server_calls.append(mock.call(fake_server, soft=soft))
self.assertEqual(5, scenario._reboot_server.call_count,
"Reboot not called 5 times")
scenario._reboot_server.assert_has_calls(server_calls)
scenario._delete_server.assert_called_once_with(fake_server)
def test_boot_soft_reboot(self): def test_boot_soft_reboot(self):
self._verify_reboot(soft=True) self._verify_reboot(soft=True)
@@ -332,10 +199,88 @@ class NovaServersTestCase(test.TestCase):
self._verify_reboot(soft=False) self._verify_reboot(soft=False)
def test_boot_and_delete_server(self): def test_boot_and_delete_server(self):
self._verify_boot_and_delete_server() fake_server = object()
scenario = servers.NovaServers()
scenario._generate_random_name = mock.MagicMock(return_value="name")
scenario._boot_server = mock.MagicMock(return_value=fake_server)
scenario._delete_server = mock.MagicMock()
scenario.sleep_between = mock.MagicMock()
scenario.boot_and_delete_server("img", 0, 10, 20, fakearg="fakearg")
scenario._boot_server.assert_called_once_with("name", "img", 0,
fakearg="fakearg")
scenario.sleep_between.assert_called_once_with(10, 20)
scenario._delete_server.assert_called_once_with(fake_server)
def test_boot_server_from_volume_and_delete(self): def test_boot_server_from_volume_and_delete(self):
self._verify_boot_server_from_volume_and_delete() fake_server = object()
scenario = servers.NovaServers()
scenario._boot_server = mock.MagicMock(return_value=fake_server)
scenario._generate_random_name = mock.MagicMock(return_value="name")
scenario.sleep_between = mock.MagicMock()
scenario._delete_server = mock.MagicMock()
fake_volume = fakes.FakeVolumeManager().create()
fake_volume.id = "volume_id"
scenario._create_volume = mock.MagicMock(return_value=fake_volume)
scenario.boot_server_from_volume_and_delete("img", 0, 5, 10, 20,
fakearg="f")
scenario._create_volume.assert_called_once_with(5, imageRef="img")
scenario._boot_server.assert_called_once_with(
"name", "img", 0,
block_device_mapping={'vda': 'volume_id:::1'},
fakearg="f")
scenario.sleep_between.assert_called_once_with(10, 20)
scenario._delete_server.assert_called_once_with(fake_server)
@mock.patch("rally.benchmark.utils.osclients")
def _prepare_boot(self, mock_osclients, mock_choice=None, nic=None,
assert_nic=False):
fake_server = mock.MagicMock()
fc = fakes.FakeClients()
mock_osclients.Clients.return_value = fc
nova = fakes.FakeNovaClient()
fc.get_nova_client = lambda: nova
temp_keys = ["username", "password", "tenant_name", "auth_url"]
users_endpoints = [dict(zip(temp_keys, temp_keys))]
clients = butils.create_openstack_clients(users_endpoints,
temp_keys)[0]
scenario = servers.NovaServers(clients=clients)
scenario._boot_server = mock.MagicMock(return_value=fake_server)
scenario._generate_random_name = mock.MagicMock(return_value="name")
kwargs = {'fakearg': 'f'}
expected_kwargs = {'fakearg': 'f'}
assert_nic = nic or assert_nic
if nic:
kwargs['nics'] = nic
if assert_nic:
nova.networks.create('net-1')
mock_choice.return_value = nova.networks.create('net-2')
expected_kwargs['nics'] = nic or [{'net-id': 'net-2'}]
print(kwargs)
print(expected_kwargs)
return scenario, kwargs, expected_kwargs
@mock.patch("rally.benchmark.scenarios.nova.servers.random.choice")
def _verify_boot_server(self, mock_choice, nic=None, assert_nic=False):
scenario, kwargs, expected_kwargs = \
self._prepare_boot(mock_choice=mock_choice,
nic=nic, assert_nic=assert_nic)
scenario.boot_server("img", 0, **kwargs)
scenario._boot_server.assert_called_once_with("name", "img", 0,
**expected_kwargs)
def test_boot_runcommand_delete_server(self): def test_boot_runcommand_delete_server(self):
self._verify_boot_runcommand_delete_server() self._verify_boot_runcommand_delete_server()
@@ -350,32 +295,43 @@ class NovaServersTestCase(test.TestCase):
def test_boot_server_random_nic(self): def test_boot_server_random_nic(self):
self._verify_boot_server(nic=None, assert_nic=True) self._verify_boot_server(nic=None, assert_nic=True)
def test_boot_server_from_volume_random_nic(self): @mock.patch("rally.benchmark.scenarios.nova.servers.random.choice")
self._verify_boot_server_from_volume(nic=None, assert_nic=True) def test_boot_server_from_volume_random_nic(self, mock_choice):
scenario, kwargs, expected_kwargs = \
self._prepare_boot(mock_choice=mock_choice, nic=None,
assert_nic=True)
@mock.patch(NOVA_SERVERS + "._generate_random_name") fake_volume = fakes.FakeVolumeManager().create()
@mock.patch(NOVA_SERVERS + "._delete_image") fake_volume.id = "volume_id"
@mock.patch(NOVA_SERVERS + "._delete_server") scenario._create_volume = mock.MagicMock(return_value=fake_volume)
@mock.patch(NOVA_SERVERS + "._create_image")
@mock.patch(NOVA_SERVERS + "._boot_server")
def test_snapshot_server(self, mock_boot, mock_create_image,
mock_delete_server, mock_delete_image,
mock_random_name):
scenario.boot_server_from_volume("img", 0, 5, **kwargs)
scenario._create_volume.assert_called_once_with(5, imageRef="img")
scenario._boot_server.assert_called_once_with(
"name", "img", 0,
block_device_mapping={"vda": "volume_id:::1"},
**expected_kwargs)
def test_snapshot_server(self):
fake_server = object() fake_server = object()
fake_image = fakes.FakeImageManager().create() fake_image = fakes.FakeImageManager().create()
fake_image.id = "image_id" fake_image.id = "image_id"
mock_random_name.return_value = "random_name" scenario = servers.NovaServers()
mock_boot.return_value = fake_server scenario._generate_random_name = mock.MagicMock(return_value="name")
mock_create_image.return_value = fake_image scenario._boot_server = mock.MagicMock(return_value=fake_server)
servers.NovaServers.snapshot_server("i", 0, fakearg=2) scenario._create_image = mock.MagicMock(return_value=fake_image)
scenario._delete_server = mock.MagicMock()
scenario._delete_image = mock.MagicMock()
mock_boot.assert_has_calls([ scenario.snapshot_server("i", 0, fakearg=2)
mock.call("random_name", "i", 0, fakearg=2),
mock.call("random_name", "image_id", 0, fakearg=2)]) scenario._boot_server.assert_has_calls([
mock_create_image.assert_called_once_with(fake_server) mock.call("name", "i", 0, fakearg=2),
mock_delete_server.assert_has_calls([ mock.call("name", "image_id", 0, fakearg=2)])
scenario._create_image.assert_called_once_with(fake_server)
scenario._delete_server.assert_has_calls([
mock.call(fake_server), mock.call(fake_server),
mock.call(fake_server)]) mock.call(fake_server)])
mock_delete_image.assert_called_once_with(fake_image) scenario._delete_image.assert_called_once_with(fake_image)

View File

@@ -44,7 +44,7 @@ class NovaScenarioTestCase(test.TestCase):
def test_generate_random_name(self): def test_generate_random_name(self):
for length in [8, 16, 32, 64]: for length in [8, 16, 32, 64]:
name = utils.NovaScenario._generate_random_name(length) name = utils.NovaScenario()._generate_random_name(length)
self.assertEqual(len(name), length) self.assertEqual(len(name), length)
self.assertTrue(name.isalpha()) self.assertTrue(name.isalpha())
@@ -77,15 +77,18 @@ class NovaScenarioTestCase(test.TestCase):
fsm.create_image = lambda svr, name: fake_image.id fsm.create_image = lambda svr, name: fake_image.id
temp_keys = ["username", "password", "tenant_name", "auth_url"] temp_keys = ["username", "password", "tenant_name", "auth_url"]
users_endpoints = [dict(zip(temp_keys, temp_keys))] users_endpoints = [dict(zip(temp_keys, temp_keys))]
utils.NovaScenario._clients = butils.\
create_openstack_clients(users_endpoints, temp_keys)[0] tmp_clients = butils.create_openstack_clients(users_endpoints,
temp_keys)[0]
novascenario = utils.NovaScenario(clients=tmp_clients)
utils.utils = mock_rally_utils utils.utils = mock_rally_utils
utils.bench_utils.get_from_manager = lambda: get_from_mgr utils.bench_utils.get_from_manager = lambda: get_from_mgr
utils.NovaScenario._boot_server("s1", "i1", 1) novascenario._boot_server("s1", "i1", 1)
utils.NovaScenario._create_image(fake_server) novascenario._create_image(fake_server)
utils.NovaScenario._suspend_server(fake_server) novascenario._suspend_server(fake_server)
utils.NovaScenario._delete_server(fake_server) novascenario._delete_server(fake_server)
expected = [ expected = [
mock.call.wait_for(fake_server, is_ready=_is_ready, mock.call.wait_for(fake_server, is_ready=_is_ready,
@@ -105,7 +108,7 @@ class NovaScenarioTestCase(test.TestCase):
self.assertEqual(expected, mock_rally_utils.mock_calls) self.assertEqual(expected, mock_rally_utils.mock_calls)
def test_server_reboot(self): def test_server_reboot(self):
utils.NovaScenario._reboot_server(self.server) utils.NovaScenario()._reboot_server(self.server)
self.server.reboot.assert_called_once_with(reboot_type='SOFT') self.server.reboot.assert_called_once_with(reboot_type='SOFT')
self.wait_for.mock.assert_called_once_with(self.server, self.wait_for.mock.assert_called_once_with(self.server,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -115,7 +118,7 @@ class NovaScenarioTestCase(test.TestCase):
self.res_is.mock.assert_has_calls(mock.call('ACTIVE')) self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))
def test_server_start(self): def test_server_start(self):
utils.NovaScenario._start_server(self.server) utils.NovaScenario()._start_server(self.server)
self.server.start.assert_called_once_with() self.server.start.assert_called_once_with()
self.wait_for.mock.assert_called_once_with(self.server, self.wait_for.mock.assert_called_once_with(self.server,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -125,7 +128,7 @@ class NovaScenarioTestCase(test.TestCase):
self.res_is.mock.assert_has_calls(mock.call('ACTIVE')) self.res_is.mock.assert_has_calls(mock.call('ACTIVE'))
def test_server_stop(self): def test_server_stop(self):
utils.NovaScenario._stop_server(self.server) utils.NovaScenario()._stop_server(self.server)
self.server.stop.assert_called_once_with() self.server.stop.assert_called_once_with()
self.wait_for.mock.assert_called_once_with(self.server, self.wait_for.mock.assert_called_once_with(self.server,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -135,7 +138,7 @@ class NovaScenarioTestCase(test.TestCase):
self.res_is.mock.assert_has_calls(mock.call('SHUTOFF')) self.res_is.mock.assert_has_calls(mock.call('SHUTOFF'))
def test_server_rescue(self): def test_server_rescue(self):
utils.NovaScenario._rescue_server(self.server) utils.NovaScenario()._rescue_server(self.server)
self.server.rescue.assert_called_once_with() self.server.rescue.assert_called_once_with()
self.wait_for.mock.assert_called_once_with(self.server, self.wait_for.mock.assert_called_once_with(self.server,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -145,7 +148,7 @@ class NovaScenarioTestCase(test.TestCase):
self.res_is.mock.assert_has_calls(mock.call('RESCUE')) self.res_is.mock.assert_has_calls(mock.call('RESCUE'))
def test_server_unrescue(self): def test_server_unrescue(self):
utils.NovaScenario._unrescue_server(self.server) utils.NovaScenario()._unrescue_server(self.server)
self.server.unrescue.assert_called_once_with() self.server.unrescue.assert_called_once_with()
self.wait_for.mock.assert_called_once_with(self.server, self.wait_for.mock.assert_called_once_with(self.server,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -159,7 +162,7 @@ class NovaScenarioTestCase(test.TestCase):
def test_delete_all_servers(self, mock_clients, mock_isnone): def test_delete_all_servers(self, mock_clients, mock_isnone):
mock_clients("nova").servers.list.return_value = [self.server, mock_clients("nova").servers.list.return_value = [self.server,
self.server1] self.server1]
utils.NovaScenario._delete_all_servers() utils.NovaScenario()._delete_all_servers()
expected = [ expected = [
mock.call(self.server, is_ready=mock_isnone, mock.call(self.server, is_ready=mock_isnone,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -171,7 +174,7 @@ class NovaScenarioTestCase(test.TestCase):
self.assertEqual(expected, self.wait_for.mock.mock_calls) self.assertEqual(expected, self.wait_for.mock.mock_calls)
def test_delete_image(self): def test_delete_image(self):
utils.NovaScenario._delete_image(self.image) utils.NovaScenario()._delete_image(self.image)
self.image.delete.assert_called_once_with() self.image.delete.assert_called_once_with()
self.wait_for.mock.assert_called_once_with(self.image, self.wait_for.mock.assert_called_once_with(self.image,
update_resource=self.gfm(), update_resource=self.gfm(),
@@ -184,7 +187,7 @@ class NovaScenarioTestCase(test.TestCase):
def test_boot_servers(self, mock_clients): def test_boot_servers(self, mock_clients):
mock_clients("nova").servers.list.return_value = [self.server, mock_clients("nova").servers.list.return_value = [self.server,
self.server1] self.server1]
utils.NovaScenario._boot_servers('prefix', 'image', 'flavor', 2) utils.NovaScenario()._boot_servers('prefix', 'image', 'flavor', 2)
expected = [ expected = [
mock.call(self.server, is_ready=self.res_is.mock(), mock.call(self.server, is_ready=self.res_is.mock(),
update_resource=self.gfm(), update_resource=self.gfm(),

View File

@@ -54,65 +54,47 @@ class ScenarioTestCase(test.TestCase):
def test_cleanup(self): def test_cleanup(self):
base.Scenario.cleanup() base.Scenario.cleanup()
def test_sleep_between(self): @mock.patch("rally.benchmark.base.time.sleep")
base.Scenario.idle_time = 0 @mock.patch("rally.benchmark.base.random.uniform")
with mock.patch("rally.benchmark.base.random.uniform") as mock_uniform: def test_sleep_between(self, mock_uniform, mock_sleep):
scenario = base.Scenario()
mock_uniform.return_value = 10 mock_uniform.return_value = 10
with mock.patch("rally.benchmark.base.time.sleep") as mock_sleep: scenario.sleep_between(5, 15)
base.Scenario.sleep_between(5, 15) scenario.sleep_between(10, 10)
base.Scenario.sleep_between(10, 10)
expected = [ expected = [mock.call(5, 15), mock.call(10, 10)]
mock.call(5, 15),
mock.call(10, 10),
]
self.assertEqual(mock_uniform.mock_calls, expected) self.assertEqual(mock_uniform.mock_calls, expected)
expected = [ expected = [mock.call(10), mock.call(10)]
mock.call(10),
mock.call(10)
]
self.assertEqual(mock_sleep.mock_calls, expected) self.assertEqual(mock_sleep.mock_calls, expected)
self.assertEqual(base.Scenario.idle_time, 20)
self.assertEqual(scenario.idle_time(), 20)
self.assertRaises(exceptions.InvalidArgumentsException, self.assertRaises(exceptions.InvalidArgumentsException,
base.Scenario.sleep_between, 15, 5) scenario.sleep_between, 15, 5)
self.assertRaises(exceptions.InvalidArgumentsException, self.assertRaises(exceptions.InvalidArgumentsException,
base.Scenario.sleep_between, -1, 0) scenario.sleep_between, -1, 0)
self.assertRaises(exceptions.InvalidArgumentsException, self.assertRaises(exceptions.InvalidArgumentsException,
base.Scenario.sleep_between, 0, -2) scenario.sleep_between, 0, -2)
def test_context(self): def test_context(self):
context = mock.MagicMock()
context = {"test": "context"} scenario = base.Scenario(context=context)
self.assertEqual(context, scenario.context())
class Scenario(base.Scenario):
@classmethod
def init(cls, config):
return context
Scenario._context = Scenario.init({})
self.assertEqual(context, Scenario.context())
def test_clients(self): def test_clients(self):
nova_client = mock.MagicMock()
nova_client = object() glance_client = mock.MagicMock()
glance_client = object()
clients = {"nova": nova_client, "glance": glance_client} clients = {"nova": nova_client, "glance": glance_client}
class Scenario(base.Scenario): scenario = base.Scenario(clients=clients)
pass self.assertEqual(nova_client, scenario.clients("nova"))
self.assertEqual(glance_client, scenario.clients("glance"))
Scenario._clients = clients
self.assertEqual(nova_client, Scenario.clients("nova"))
self.assertEqual(glance_client, Scenario.clients("glance"))
def test_admin_clients(self): def test_admin_clients(self):
nova_client = mock.MagicMock()
nova_client = object() glance_client = mock.MagicMock()
glance_client = object()
clients = {"nova": nova_client, "glance": glance_client} clients = {"nova": nova_client, "glance": glance_client}
class Scenario(base.Scenario): scenario = base.Scenario(admin_clients=clients)
pass self.assertEqual(nova_client, scenario.admin_clients("nova"))
self.assertEqual(glance_client, scenario.admin_clients("glance"))
Scenario._admin_clients = clients
self.assertEqual(nova_client, Scenario.admin_clients("nova"))
self.assertEqual(glance_client, Scenario.admin_clients("glance"))

View File

@@ -395,22 +395,16 @@ class FakeClients(object):
class FakeScenario(base.Scenario): class FakeScenario(base.Scenario):
idle_time = 0 def idle_time(self):
return 0
@classmethod def do_it(self, **kwargs):
def class_init(cls, endpoints):
pass pass
@classmethod def too_long(self, **kwargs):
def do_it(cls, **kwargs):
pass pass
@classmethod def something_went_wrong(self, **kwargs):
def too_long(cls, **kwargs):
pass
@classmethod
def something_went_wrong(cls, **kwargs):
raise Exception("Something went wrong") raise Exception("Something went wrong")