Moving of EC2, Fuel and Glance scenarios into separate classes

Since current scenario implementation transforms method to class
at runtime, it is reasonable to have class-based scenario
implementation which will be much simpler to use behind the scenes.

This class should be based on Scenario and do not break compatibility.
The only required method is run() which is actually a body of scenario.

This patch contains changes for following groups
(scenarios and tests):
/ec2/
/fuel/
/glance/

Change-Id: Idcee33340141cfa0995503332403c63352bfc6e1
This commit is contained in:
Anton Staroverov 2016-08-22 10:21:51 +03:00 committed by Staroverov Anton
parent 05a459f2f7
commit 3bfb6093aa
4 changed files with 106 additions and 90 deletions

View File

@ -19,13 +19,16 @@ from rally.task import types
from rally.task import validation
class EC2Servers(utils.EC2Scenario):
"""Benchmark scenarios for servers using EC2."""
"""Scenarios for servers using EC2."""
@validation.required_services(consts.Service.EC2)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["ec2"]})
def list_servers(self):
@validation.required_services(consts.Service.EC2)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["ec2"]},
name="EC2Servers.list_servers")
class ListServers(utils.EC2Scenario):
def run(self):
"""List all servers.
This simple scenario tests the EC2 API list function by listing
@ -33,13 +36,17 @@ class EC2Servers(utils.EC2Scenario):
"""
self._list_servers()
@types.convert(image={"type": "ec2_image"},
flavor={"type": "ec2_flavor"})
@validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.EC2)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["ec2"]})
def boot_server(self, image, flavor, **kwargs):
@types.convert(image={"type": "ec2_image"},
flavor={"type": "ec2_flavor"})
@validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.EC2)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["ec2"]},
name="EC2Servers.boot_server")
class BootServer(utils.EC2Scenario):
def run(self, image, flavor, **kwargs):
"""Boot a server.
Assumes that cleanup is done elsewhere.
@ -48,4 +55,4 @@ class EC2Servers(utils.EC2Scenario):
:param flavor: flavor to be used to boot an instance
:param kwargs: optional additional arguments for server creation
"""
self._boot_servers(image, flavor, **kwargs)
self._boot_servers(image, flavor, **kwargs)

View File

@ -21,15 +21,17 @@ from rally.task import types
from rally.task import validation
class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
"""Benchmark scenarios for Glance images."""
"""Scenarios for Glance images."""
@types.convert(image_location={"type": "path_or_url"})
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]})
def create_and_list_image(self, container_format,
image_location, disk_format, **kwargs):
@types.convert(image_location={"type": "path_or_url"})
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]},
name="GlanceImages.create_and_list_image")
class CreateAndListImage(utils.GlanceScenario, nova_utils.NovaScenario):
def run(self, container_format, image_location, disk_format, **kwargs):
"""Create an image and then list all images.
Measure the "glance image-list" command performance.
@ -53,10 +55,14 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
**kwargs)
self._list_images()
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]})
def list_images(self):
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]},
name="GlanceImages.list_images")
class ListImages(utils.GlanceScenario, nova_utils.NovaScenario):
def run(self):
"""List all images.
This simple scenario tests the glance image-list command by listing
@ -66,14 +72,16 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
uploaded for them we will be able to test the performance of
glance image-list command in this case.
"""
self._list_images()
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]})
def create_and_delete_image(self, container_format,
image_location, disk_format, **kwargs):
@validation.required_services(consts.Service.GLANCE)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance"]},
name="GlanceImages.create_and_delete_image")
class CreateAndDeleteImage(utils.GlanceScenario, nova_utils.NovaScenario):
def run(self, container_format, image_location, disk_format, **kwargs):
"""Create and then delete an image.
:param container_format: container format of image. Acceptable
@ -89,15 +97,18 @@ class GlanceImages(utils.GlanceScenario, nova_utils.NovaScenario):
**kwargs)
self._delete_image(image)
@types.convert(flavor={"type": "nova_flavor"})
@validation.flavor_exists("flavor")
@validation.required_services(consts.Service.GLANCE, consts.Service.NOVA)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance", "nova"]})
def create_image_and_boot_instances(self, container_format,
image_location, disk_format,
flavor, number_instances,
**kwargs):
@types.convert(flavor={"type": "nova_flavor"})
@validation.flavor_exists("flavor")
@validation.required_services(consts.Service.GLANCE, consts.Service.NOVA)
@validation.required_openstack(users=True)
@scenario.configure(context={"cleanup": ["glance", "nova"]},
name="GlanceImages.create_image_and_boot_instances")
class CreateImageAndBootInstances(utils.GlanceScenario,
nova_utils.NovaScenario):
def run(self, container_format, image_location, disk_format,
flavor, number_instances, **kwargs):
"""Create an image and boot several instances from it.
:param container_format: container format of image. Acceptable

View File

@ -21,14 +21,14 @@ from tests.unit import test
class EC2ServersTestCase(test.ScenarioTestCase):
def test_list_servers(self):
scenario = servers.EC2Servers()
scenario = servers.ListServers(self.context)
scenario._list_servers = mock.MagicMock()
scenario.list_servers()
scenario.run()
scenario._list_servers.assert_called_once_with()
def test_boot_server(self):
scenario = servers.EC2Servers(self.context)
scenario = servers.BootServer(self.context)
scenario._boot_servers = mock.Mock()
scenario.boot_server("foo_image", "foo_flavor", foo="bar")
scenario.run("foo_image", "foo_flavor", foo="bar")
scenario._boot_servers.assert_called_once_with(
"foo_image", "foo_flavor", foo="bar")

View File

@ -19,63 +19,61 @@ from rally.plugins.openstack.scenarios.glance import images
from tests.unit import fakes
from tests.unit import test
GLANCE_IMAGES = "rally.plugins.openstack.scenarios.glance.images.GlanceImages"
BASE = "rally.plugins.openstack.scenarios.glance.images"
class GlanceImagesTestCase(test.ScenarioTestCase):
@mock.patch(GLANCE_IMAGES + ".generate_random_name")
@mock.patch(GLANCE_IMAGES + "._list_images")
@mock.patch(GLANCE_IMAGES + "._create_image")
def test_create_and_list_image(self, mock__create_image,
mock__list_images,
mock_generate_random_name):
glance_scenario = images.GlanceImages(self.context)
mock_generate_random_name.return_value = "test-rally-image"
glance_scenario.create_and_list_image("cf", "url", "df",
fakearg="f")
mock__create_image.assert_called_once_with(
@mock.patch("%s.CreateAndListImage._list_images" % BASE)
@mock.patch("%s.CreateAndListImage._create_image" % BASE)
@mock.patch("%s.CreateAndListImage.generate_random_name" % BASE,
return_value="test-rally-image")
def test_create_and_list_image(self,
mock_random_name,
mock_create_image,
mock_list_images):
images.CreateAndListImage(self.context).run(
"cf", "url", "df", fakearg="f")
mock__list_images.assert_called_once_with()
mock_create_image.assert_called_once_with(
"cf", "url", "df", fakearg="f")
mock_list_images.assert_called_once_with()
@mock.patch(GLANCE_IMAGES + "._list_images")
def test_list_images(self, mock__list_images):
glance_scenario = images.GlanceImages(self.context)
glance_scenario.list_images()
mock__list_images.assert_called_once_with()
@mock.patch("%s.ListImages._list_images" % BASE)
def test_list_images(self, mock_list_images__list_images):
images.ListImages(self.context).run()
mock_list_images__list_images.assert_called_once_with()
@mock.patch(GLANCE_IMAGES + ".generate_random_name")
@mock.patch(GLANCE_IMAGES + "._delete_image")
@mock.patch(GLANCE_IMAGES + "._create_image")
def test_create_and_delete_image(
self, mock__create_image, mock__delete_image,
mock_generate_random_name):
glance_scenario = images.GlanceImages(self.context)
@mock.patch("%s.CreateAndDeleteImage._delete_image" % BASE)
@mock.patch("%s.CreateAndDeleteImage._create_image" % BASE)
@mock.patch("%s.CreateAndDeleteImage.generate_random_name" % BASE,
return_value="test-rally-image")
def test_create_and_delete_image(self,
mock_random_name,
mock_create_image,
mock_delete_image):
fake_image = object()
mock__create_image.return_value = fake_image
mock_generate_random_name.return_value = "test-rally-image"
glance_scenario.create_and_delete_image("cf", "url", "df",
fakearg="f")
mock_create_image.return_value = fake_image
mock__create_image.assert_called_once_with(
images.CreateAndDeleteImage(self.context).run(
"cf", "url", "df", fakearg="f")
mock__delete_image.assert_called_once_with(fake_image)
@mock.patch(GLANCE_IMAGES + "._boot_servers")
@mock.patch(GLANCE_IMAGES + "._create_image")
def test_create_image_and_boot_instances(
self, mock__create_image, mock__boot_servers):
glance_scenario = images.GlanceImages(self.context)
mock_create_image.assert_called_once_with(
"cf", "url", "df", fakearg="f")
mock_delete_image.assert_called_once_with(fake_image)
@mock.patch("%s.CreateImageAndBootInstances._boot_servers" % BASE)
@mock.patch("%s.CreateImageAndBootInstances._create_image" % BASE)
def test_create_image_and_boot_instances(self,
mock_create_image,
mock_boot_servers):
fake_image = fakes.FakeImage()
fake_servers = [mock.Mock() for i in range(5)]
mock__create_image.return_value = fake_image
mock__boot_servers.return_value = fake_servers
mock_create_image.return_value = fake_image
mock_boot_servers.return_value = fake_servers
kwargs = {"fakearg": "f"}
glance_scenario.create_image_and_boot_instances("cf", "url",
"df", "fid",
5, **kwargs)
mock__create_image.assert_called_once_with(
"cf", "url", "df")
mock__boot_servers.assert_called_once_with(
"image-id-0", "fid", 5, **kwargs)
images.CreateImageAndBootInstances(self.context).run(
"cf", "url", "df", "fid", 5, **kwargs)
mock_create_image.assert_called_once_with("cf", "url", "df")
mock_boot_servers.assert_called_once_with("image-id-0", "fid",
5, **kwargs)