Convert ResourceType classes to plugins
This also deprecates the old ResourceType classes in rally.task.types, and also deprecates types.set() in favor of types.convert(). Existing scenarios will be switched over to the new usage in a subsequent commit. Change-Id: Iacbf812f87d3c65617b2e7a992c42b8673778d6a Implements: blueprint pluggable-types
This commit is contained in:
parent
0f47b8942f
commit
aca03ef745
168
rally/plugins/openstack/types.py
Normal file
168
rally/plugins/openstack/types.py
Normal file
@ -0,0 +1,168 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from rally.common.plugin import plugin
|
||||
from rally import exceptions
|
||||
from rally.task import types
|
||||
|
||||
|
||||
@plugin.configure(name="nova_flavor")
|
||||
class Flavor(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to id.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: id matching resource
|
||||
"""
|
||||
resource_id = resource_config.get("id")
|
||||
if not resource_id:
|
||||
novaclient = clients.nova()
|
||||
resource_id = types._id_from_name(
|
||||
resource_config=resource_config,
|
||||
resources=novaclient.flavors.list(),
|
||||
typename="flavor")
|
||||
return resource_id
|
||||
|
||||
|
||||
@plugin.configure(name="ec2_flavor")
|
||||
class EC2Flavor(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to name.
|
||||
|
||||
In the case of using EC2 API, flavor name is used for launching
|
||||
servers.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: name matching resource
|
||||
"""
|
||||
resource_name = resource_config.get("name")
|
||||
if not resource_name:
|
||||
# NOTE(wtakase): gets resource name from OpenStack id
|
||||
novaclient = clients.nova()
|
||||
resource_name = types._name_from_id(
|
||||
resource_config=resource_config,
|
||||
resources=novaclient.flavors.list(),
|
||||
typename="flavor")
|
||||
return resource_name
|
||||
|
||||
|
||||
@plugin.configure(name="glance_image")
|
||||
class GlanceImage(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to id.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: id matching resource
|
||||
"""
|
||||
resource_id = resource_config.get("id")
|
||||
if not resource_id:
|
||||
glanceclient = clients.glance()
|
||||
resource_id = types._id_from_name(
|
||||
resource_config=resource_config,
|
||||
resources=list(glanceclient.images.list()),
|
||||
typename="image")
|
||||
return resource_id
|
||||
|
||||
|
||||
@plugin.configure(name="ec2_image")
|
||||
class EC2Image(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to EC2 id.
|
||||
|
||||
If OpenStack resource id is given, this function gets resource name
|
||||
from the id and then gets EC2 resource id from the name.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: EC2 id matching resource
|
||||
"""
|
||||
if "name" not in resource_config and "regex" not in resource_config:
|
||||
# NOTE(wtakase): gets resource name from OpenStack id
|
||||
glanceclient = clients.glance()
|
||||
resource_name = types._name_from_id(
|
||||
resource_config=resource_config,
|
||||
resources=list(glanceclient.images.list()),
|
||||
typename="image")
|
||||
resource_config["name"] = resource_name
|
||||
|
||||
# NOTE(wtakase): gets EC2 resource id from name or regex
|
||||
ec2client = clients.ec2()
|
||||
resource_ec2_id = types._id_from_name(
|
||||
resource_config=resource_config,
|
||||
resources=list(ec2client.get_all_images()),
|
||||
typename="ec2_image")
|
||||
return resource_ec2_id
|
||||
|
||||
|
||||
@plugin.configure(name="cinder_volume_type")
|
||||
class VolumeType(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to id.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: id matching resource
|
||||
"""
|
||||
resource_id = resource_config.get("id")
|
||||
if not resource_id:
|
||||
cinderclient = clients.cinder()
|
||||
resource_id = types._id_from_name(resource_config=resource_config,
|
||||
resources=cinderclient.
|
||||
volume_types.list(),
|
||||
typename="volume_type")
|
||||
return resource_id
|
||||
|
||||
|
||||
@plugin.configure(name="neutron_network")
|
||||
class NeutronNetwork(types.ResourceType):
|
||||
|
||||
@classmethod
|
||||
def transform(cls, clients, resource_config):
|
||||
"""Transform the resource config to id.
|
||||
|
||||
:param clients: openstack admin client handles
|
||||
:param resource_config: scenario config with `id`, `name` or `regex`
|
||||
|
||||
:returns: id matching resource
|
||||
"""
|
||||
resource_id = resource_config.get("id")
|
||||
if resource_id:
|
||||
return resource_id
|
||||
else:
|
||||
neutronclient = clients.neutron()
|
||||
for net in neutronclient.list_networks()["networks"]:
|
||||
if net["name"] == resource_config.get("name"):
|
||||
return net["id"]
|
||||
|
||||
raise exceptions.InvalidScenarioArgument(
|
||||
"Neutron network with name '{name}' not found".format(
|
||||
name=resource_config.get("name")))
|
327
tests/unit/plugins/openstack/test_types.py
Normal file
327
tests/unit/plugins/openstack/test_types.py
Normal file
@ -0,0 +1,327 @@
|
||||
# Copyright (C) 2014 Yahoo! Inc. All Rights Reserved.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from rally import exceptions
|
||||
from rally.plugins.openstack import types
|
||||
from tests.unit import fakes
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
class FlavorTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(FlavorTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.tiny",
|
||||
id="1"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.nano",
|
||||
id="42"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.large",
|
||||
id="44"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.large",
|
||||
id="45"))
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": "42"}
|
||||
flavor_id = types.Flavor.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(flavor_id, "42")
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "m1.nano"}
|
||||
flavor_id = types.Flavor.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(flavor_id, "42")
|
||||
|
||||
def test_transform_by_name_no_match(self):
|
||||
resource_config = {"name": "m1.medium"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_name_multiple_match(self):
|
||||
resource_config = {"name": "m1.large"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex(self):
|
||||
resource_config = {"regex": "m(1|2)\.nano"}
|
||||
flavor_id = types.Flavor.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(flavor_id, "42")
|
||||
|
||||
def test_transform_by_regex_multiple_match(self):
|
||||
resource_config = {"regex": "^m1"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex_no_match(self):
|
||||
resource_config = {}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
|
||||
class EC2FlavorTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(EC2FlavorTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.tiny",
|
||||
id="1"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.nano",
|
||||
id="2"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.large",
|
||||
id="3"))
|
||||
self.clients.nova().flavors._cache(fakes.FakeResource(name="m1.xlarge",
|
||||
id="3"))
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "m1.nano"}
|
||||
flavor_name = types.EC2Flavor.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(flavor_name, "m1.nano")
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": "2"}
|
||||
flavor_name = types.EC2Flavor.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(flavor_name, "m1.nano")
|
||||
|
||||
def test_transform_by_id_no_match(self):
|
||||
resource_config = {"id": "4"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_id_multiple_match(self):
|
||||
resource_config = {"id": "3"}
|
||||
self.assertRaises(exceptions.MultipleMatchesFound,
|
||||
types.EC2Flavor.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
|
||||
class GlanceImageTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GlanceImageTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
image1 = fakes.FakeResource(name="cirros-0.3.4-uec", id="100")
|
||||
self.clients.glance().images._cache(image1)
|
||||
image2 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk", id="101")
|
||||
self.clients.glance().images._cache(image2)
|
||||
image3 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="102")
|
||||
self.clients.glance().images._cache(image3)
|
||||
image4 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="103")
|
||||
self.clients.glance().images._cache(image4)
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": "100"}
|
||||
image_id = types.GlanceImage.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(image_id, "100")
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "^cirros-0.3.4-uec$"}
|
||||
image_id = types.GlanceImage.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(image_id, "100")
|
||||
|
||||
def test_transform_by_name_no_match(self):
|
||||
resource_config = {"name": "cirros-0.3.4-uec-boot"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.GlanceImage.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_name_match_multiple(self):
|
||||
resource_config = {"name": "cirros-0.3.4-uec-ramdisk-copy"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.GlanceImage.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex(self):
|
||||
resource_config = {"regex": "-uec$"}
|
||||
image_id = types.GlanceImage.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(image_id, "100")
|
||||
|
||||
def test_transform_by_regex_match_multiple(self):
|
||||
resource_config = {"regex": "^cirros"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.GlanceImage.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex_no_match(self):
|
||||
resource_config = {"regex": "-boot$"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.GlanceImage.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
|
||||
class EC2ImageTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(EC2ImageTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
image1 = fakes.FakeResource(name="cirros-0.3.4-uec", id="100")
|
||||
self.clients.glance().images._cache(image1)
|
||||
image2 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk", id="102")
|
||||
self.clients.glance().images._cache(image2)
|
||||
image3 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="102")
|
||||
self.clients.glance().images._cache(image3)
|
||||
image4 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="103")
|
||||
self.clients.glance().images._cache(image4)
|
||||
|
||||
ec2_image1 = fakes.FakeResource(name="cirros-0.3.4-uec", id="200")
|
||||
ec2_image2 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk",
|
||||
id="201")
|
||||
ec2_image3 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="202")
|
||||
ec2_image4 = fakes.FakeResource(name="cirros-0.3.4-uec-ramdisk-copy",
|
||||
id="203")
|
||||
|
||||
self.clients.ec2().get_all_images = mock.Mock(
|
||||
return_value=[ec2_image1, ec2_image2, ec2_image3, ec2_image4])
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "^cirros-0.3.4-uec$"}
|
||||
ec2_image_id = types.EC2Image.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(ec2_image_id, "200")
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": "100"}
|
||||
ec2_image_id = types.EC2Image.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(ec2_image_id, "200")
|
||||
|
||||
def test_transform_by_id_no_match(self):
|
||||
resource_config = {"id": "101"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_id_match_multiple(self):
|
||||
resource_config = {"id": "102"}
|
||||
self.assertRaises(exceptions.MultipleMatchesFound,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_name_no_match(self):
|
||||
resource_config = {"name": "cirros-0.3.4-uec-boot"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_name_match_multiple(self):
|
||||
resource_config = {"name": "cirros-0.3.4-uec-ramdisk-copy"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex(self):
|
||||
resource_config = {"regex": "-uec$"}
|
||||
ec2_image_id = types.EC2Image.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(ec2_image_id, "200")
|
||||
|
||||
def test_transform_by_regex_match_multiple(self):
|
||||
resource_config = {"regex": "^cirros"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
def test_transform_by_regex_no_match(self):
|
||||
resource_config = {"regex": "-boot$"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.EC2Image.transform, self.clients,
|
||||
resource_config)
|
||||
|
||||
|
||||
class VolumeTypeTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(VolumeTypeTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
volume_type1 = fakes.FakeResource(name="lvmdriver-1", id=100)
|
||||
self.clients.cinder().volume_types._cache(volume_type1)
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": 100}
|
||||
volumetype_id = types.VolumeType.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(volumetype_id, 100)
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "lvmdriver-1"}
|
||||
volumetype_id = types.VolumeType.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(volumetype_id, 100)
|
||||
|
||||
def test_transform_by_name_no_match(self):
|
||||
resource_config = {"name": "nomatch-1"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.VolumeType.transform,
|
||||
self.clients, resource_config)
|
||||
|
||||
def test_transform_by_regex(self):
|
||||
resource_config = {"regex": "^lvm.*-1"}
|
||||
volumetype_id = types.VolumeType.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(volumetype_id, 100)
|
||||
|
||||
def test_transform_by_regex_no_match(self):
|
||||
resource_config = {"regex": "dd"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.VolumeType.transform,
|
||||
self.clients, resource_config)
|
||||
|
||||
|
||||
class NeutronNetworkTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NeutronNetworkTestCase, self).setUp()
|
||||
self.clients = fakes.FakeClients()
|
||||
net1_data = {"network": {
|
||||
"name": "net1"
|
||||
}}
|
||||
network1 = self.clients.neutron().create_network(net1_data)
|
||||
self.net1_id = network1["network"]["id"]
|
||||
|
||||
def test_transform_by_id(self):
|
||||
resource_config = {"id": self.net1_id}
|
||||
network_id = types.NeutronNetwork.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(network_id, self.net1_id)
|
||||
|
||||
def test_transform_by_name(self):
|
||||
resource_config = {"name": "net1"}
|
||||
network_id = types.NeutronNetwork.transform(
|
||||
clients=self.clients, resource_config=resource_config)
|
||||
self.assertEqual(network_id, self.net1_id)
|
||||
|
||||
def test_transform_by_name_no_match(self):
|
||||
resource_config = {"name": "nomatch-1"}
|
||||
self.assertRaises(exceptions.InvalidScenarioArgument,
|
||||
types.NeutronNetwork.transform,
|
||||
self.clients, resource_config)
|
Loading…
x
Reference in New Issue
Block a user